Wie sende ich Variablen von JavaScript nach Flask via jQuery?
Hallo,
ich bin in JavaScript/jQuery und auch Python/Flask noch ein ziemlicher Anfänger. Ich versuche gerade, einfach nur ein JSON-Objekt aus JavaScript in einem HTML-Template mit Flask anzuzeigen.
Hier mein Code:
Flask:
from flask import Flask,request, render_template
app = Flask(__name__)
@app.route("/")
def rofl():
return render_template("test.html")
@app.route("/test", methods=['POST'])
def test():
Namensliste = request.get_json(True)
print(Namensliste)
return render_template("rofl.html", Namensliste=Namensliste)
if __name__ == '__main__':
app.run(port=5200)
test.html:
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="#" method="post">
<button type="button" onclick="JSONTest()"> Send UserInfo</button>
</form>
</body>
rofl.html:
<head>
<meta charset="UTF-8">
<title>Titel</title>
</head>
<body>
NamensListe: {{Namensliste}}
</body>
JavaScript-Datei:
var myJason = {
"name1" : "Jens",
"name2" : "Josef",
"name3" : "Johannes"
}
function JSONTest() {
var MyJason= JSON.stringify(myJason);
console.log(MyJason)
$.ajax({
type: 'POST',
url: '/test',
data: MyJason,
success: function(data) {
console.log(data, "Rückmeldung1");
}});
}
Wie mein Code eigentlich funktionieren soll ist: Ich rufe die Route "/" auf, drücke auf den Button: "JSONTest()" und meine Funktion sendet via jQuery mein JSON-Objekt an "/test". Dort wird das Objekt in Namensliste gespeichert und rofl.html mit der Namensliste darin aufgerufen.
Ich weiß, dass hier wahrscheinlich viele Grundlagenfehler drin sind, aber ich habe wirklich ewig lang gegooglet und finde einfach nicht, wie man es richtig macht.
Danke schon einmal für jede Idee.
Welche Zwischenwerte / Rückmeldungen erhältst du?
console.log(MyJason)=print(Namensliste)= {"name1" : "Jens", "name2" : "Josef", "name3" : "Johannes" }, rofl.html wird aber nicht aufgerufen als neue Seite.
2 Antworten
Den Aufruf einer neuen Seite kannst du nicht erwarten, da der AJAX-Request eine unabhängige HTTP-Anfrage an deinen Server ist (gerade da man oft nicht die komplette Seite neu laden möchte, verwendet man Requests via AJAX/Fetch). Das Ergebnis, welches deine Controller-Methode test zurückgibt, wird in den data-Parameter deiner Callback-Funktion:
success: function(data) {
console.log(data, "Rückmeldung1");
}
geschleust. Du könntest diese Daten nun mit JavaScript in das DOM einfügen. Du brauchst ein Element, dem du den neuen Inhalt anhängen kannst. Ich würde mir dafür ein eigenes Element anlegen:
<p id="output"></p>
Deine Callback-Funktion:
success: function(data) {
console.log(data, "Rückmeldung1");
document.getElementById("output").innerText = data;
}
Des Weiteren sollte nochmal der Controller angepasst werden, da du ja nur die Namensliste ausgeben lassen möchtest:
def test():
Namensliste = request.get_json(True)
print(Namensliste)
return "NamensListe: " + Namensliste
Wenn du aber auf eine neue Seite leiten möchtest, nutze stattdessen nur das Formular:
<form action="/test" method="post">
<input type="hidden" name="name1" value="Jens">
<input type="hidden" name="name2" value="Josef">
<input type="hidden" name="name3" value="Johannes">
<button>Send UserInfo</button>
</form>
Ich habe die Werte hier in einzelne versteckte Felder gesetzt und du würdest sie im Controller aus dem request.form-Dictionary holen.
Beispiel:
name1 = request.form.get("name1")
Du könntest aber auch alle Werte in ein Feld schreiben (kommasepariert, o.ä.). Noch eine Methodik wäre diese:
<form action="/test" method="post">
<input type="hidden" name="name[]" value="Jens">
<input type="hidden" name="name[]" value="Josef">
<input type="hidden" name="name[]" value="Johannes">
<button>Send UserInfo</button>
</form>
Im Controller:
names = request.form.getlist("name[]")
In names stände dann eine Liste mit allen Namen.
PS.: Bei all deinen HTML-Dateien fehlt (in der ersten Zeile) seltsamerweise der Doctype.
<!doctype html>
Ergänze ihn noch.
Wie gesagt: Ein AJAX-Request dient dazu, eine parallele Anfrage an den Server zu senden, damit eben kein Neuladen der Seite notwendig ist. Wenn du das nicht möchtest, verwende kein AJAX und füge deinen Wert einfach nur in irgendein Formularfeld ein. Wenn es notwendig ist, geht das auch via JavaScript.
<form action="/test" method="post" name="someform">
<input name="jsondata" type="hidden">
<button>Send</button>
</form>
<script>
document.forms["someform"].addEventListener("submit", evt => {
const field = document.querySelector("input[name='jsondata']");
field.value = "your JSON data ...";
});
</script>
Ich habe keine Erfahrung in Python bzw. Flask, aber vielleicht hilft dir meine Antwort trotzdem weiter. Du schickst deine Daten als FormData. Das heisst, dass deine Daten, welche du mit JQuery verschickst im Header deiner POST-Request gespeichert sind, nämlich als Key-Value-Pairs.
In deinem Python Code sieht es für mich so aus, als ob du den Body der Anfrage benutzt. Dieser ist aber leer. Du musst also mit Flask irgendwie die Post-Felder auslesen (name1, name2 und name2).
Danke erstmal für die Antwort. Den Doctype habe ich aus Übersichtlichkeit weggelassen.
Also ganz allgemein will ich einfach JSON-Objekte von Javascript nach Flask senden und diesen in meinen Templates auf einer neuen Route verwenden. Gibt es dafür eine einfache Möglichkeit. Mir erschließt sich nicht ganz der nutzen von
function JSONTest() {
var MyJason= JSON.stringify(myJason);
console.log(MyJason)
$.ajax({
type: 'POST',
url: '/test',
data: MyJason,
success: function(data) {
console.log(data, "Rückmeldung1");
}});
dem Abschnitt, wenn der return aus "/test" in data gespeichert wird. Kann ich nicht irgendwie das JSON-Objekt einfach zu Flask senden und dort dann nach diesem Schema einfach fortfahren?:
return render_template("rofl.html", Namensliste=Namensliste)