Als ich ein Projekt mit Flask implementiert habe, Im Registrierungsformular für öffentliche Schlüssel (Textbereich), das zu "Kopieren und Einfügen" führte, Es gab einen Endbenutzer, der die Datei gelöscht hat. Ich dachte, dass es Leute gibt, die das tun, aber ich habe nachgeforscht, ob ich es schaffen kann ... StackOverflow: Load Textfile via Drag and Drop on Textarea Ich habe das gefunden.
Ich fand, dass ich JavaScript unerwartet leicht machen konnte, also Ich habe es mit Flask implementiert.
Flask Definieren Sie zunächst das Registrierungsformular für öffentliche Schlüssel in Flask als FORM-Klasse RegisterForm. Bei der Überprüfung öffentlicher Schlüssel wird die Bibliothek sshpubkeys verwendet, die nicht das Hauptthema ist.
Es ist eine Testanwendung, die nur die verifizierten Daten der Formulardaten empfängt und anzeigt.
import os
from flask import (
Flask,
request,
render_template,
redirect,
url_for,
)
from flask_wtf import FlaskForm
from wtforms import TextAreaField, SubmitField, ValidationError
from wtforms.validators import InputRequired
from sshpubkeys import SSHKey, InvalidKeyError, MalformedDataError
class RegistForm(FlaskForm):
pubkey = TextAreaField("PublicKey",validators=[InputRequired()])
submit = SubmitField("OK")
reset = SubmitField("RESET")
def validate_pubkey(self, field):
if field.data.find('\n') >1:
raise ValidationError("Too Many Publickey")
sshpubkey = SSHKey(field.data, strict=True)
if sshpubkey.key_type != b"ssh-rsa":
raise ValidationError("Invalid Key Type")
try:
sshpubkey.parse()
except InvalidKeyError as err:
raise ValidationError("Invalid PublicKey")
except MalformedDataError as err:
raise ValidationError("Malformed key Error")
except NotImplementedError as err:
raise ValidationError("Undefined Error")
app = Flask(__name__, static_folder='static')
app.config['SECRET_KEY']='12345678901234567890'
@app.route("/", endpoint="register", methods=["GET", "POST"])
def register():
form = RegistForm()
if request.method == "GET":
return render_template("test.html",
form=form,
endpoint="register")
if form.validate_on_submit():
return form.pubkey.data
else:
print(f'vaslidation error')
return redirect(url_for("register"))
if __name__ == "__main__":
app.run(
host=os.getenv("APP_HOST", "localhost"),
port=os.getenv("APP_PORT", 8080),
debug=True,
)
JavaScript
Bereiten Sie die folgenden Funktionen in static / functions.js vor.
function dropfile(file) {
var reader = new FileReader();
reader.onload = function(e) {
notepad.value = e.target.result.replace(/(?:\r\n|\r|\n)/g, '');
};
reader.readAsText(file, "UTF-8");
};
notepad.ondrop = function(e) {
e.preventDefault();
var file = e.dataTransfer.files[0];
dropfile(file);
};
Ich verwende ein DataTransfer-Objekt, aber nicht alle Browser veröffentlichen das Objekt. Wenn es ein moderner Browser ist, sollte es kein Problem geben ...
HTML
Eigentlich ist dies das einzige, was ein Händchen zu sein scheint. Die Attribut-ID "notepad" wird dem Feld der in forms.py definierten Klasse zugewiesen.
{% extends "base.html" %}
{% block contents %}
<form action="{{ url_for( endpoint ) }}" method="post">
{{ form.hidden_tag() }}
{{ form.pubkey(id="notepad", raws=6, cols=80,
placeholder="Copy&Past or Drag&Drop here!") }}
{{ form.submit }}
{{ form.reset }}
</form>
{% endblock contents %}
"Zeilen", "Spalten" und "Platzhalter" können in der Klassendefinition für "render_kw" im Wörterbuchformat vergeben werden, aber ich denke, es ist besser, nicht viel mit dem Zeichnen in der Klasse zu tun zu haben.
render_kw={"rows": 6, "cols": 80, "placeholder": "Copy&Paste" }
Dies hat auch nichts mit dem Hauptthema zu tun, aber einige Leute könnten daran interessiert sein. Bereiten Sie vorerst eine solche base.html vor.
{% from "_defaults.html" import render_htmlattribs, render_styles, render_scripts %}
{% block doc -%}
<!DOCTYPE html>
<html{% block html_attribs %} {{ render_htmlattribs() }}{% endblock html_attribs %}>
{%- block html %}
<head>
{%- block head %}
<title>{% block title %}{{ render_title() }}{% endblock title %}</title>
{%- block metas %}
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
{%- endblock metas %}
{%- block favicon %} {%- endblock favicon %}
{%- block styles %}
{{ render_styles() }}
{%- endblock styles %}
{%- endblock head %}
</head>
<body{% block body_attribs %}{% endblock body_attribs %}>
{%- block body %}
{% block contents %} {% endblock contents %}
{% block footer %}
{{ render_footer() }}
{%- endblock footer %}
{% block scripts %}
{{ render_scripts() }}
{%- endblock scripts %}
{%- endblock body %}
</body>
{%- endblock html %}
</html>
{% endblock doc -%}
Das in _defaults.html definierte Makro sieht folgendermaßen aus: Ich benutze es die ganze Zeit, also versuche ich Bootstrap und JQuery zu laden. Das musst du nicht haben. Sie müssen lediglich static / functions.js laden.
{% macro render_htmlattribs() -%}
lang="ja"
{%- endmacro %}
{% macro render_styles() %}
<link href="/static/bootstrap-4.5.2/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/base.css" rel="stylesheet">
{% endmacro %}
{% macro render_scripts() %}
<script src="/static/jquery-3.5.1.min.js"></script>
<script src="/static/bootstrap-4.5.2/js/bootstrap.min.js"></script>
<script src="/static/functions.js"></script>
{% endmacro %}
Recommended Posts