How to send out an AJAX request to Flask - python

I'm trying to send an AJAX request to my server to obtain a string and save it.
This is my relevant JS:
var token = "";
$.ajax({
type: 'GET',
url: 'payment_demo.py',
success: function(data) {
token = data;
},
});
This is my relevant Python (Flask):
#app.route('/')
def home():
return render_template('official_checkout_page.html')
#app.route("/", methods=["GET"])
def client_token():
return gateway.client_token.generate()
The HTML and JS both are loaded, but I get a 404 not found on the ajax URL (payment_demo.py).
Right now the locations are /payment_demo.py, /static/official_checkout_page.js (the JS file), /templates/official_checkout_page.html (the HTML file, if necessary). What am I doing wrong?

the ajax request just get data from the spesifik url from server/api resource, please try this code
$.ajax({
type: 'GET',
url: '/api/token',
success: function(data) {
token = data;
},
});
the example Flask code from backend server
from flask import jsonify, render_template
#app.route('/')
def home():
return render_template('official_checkout_page.html')
#app.route("/api/token", methods=["GET"])
def client_token():
return jsonify({"data":gateway.client_token.generate()})

Related

Flask set_cookie not carrying over to other routes

I am having an issue with the SetCookie which I can't get it to work. I've seen too many SO topics but no success so far. Here is my situation:
I have an Ajax POST call which sends a token from my frontend (JavaScript) to my backend (Flask). This Ajax call send the token to the route /sessionLogin:
#app.route('/sessionLogin', methods=['POST'])
def session_login():
id_token = request.form['idToken']
csrfToken = request.form['csrfToken']
expires_in = datetime.timedelta(minutes=120)
expires = datetime.datetime.now() + expires_in
session_cookie = auth.create_session_cookie(id_token, expires_in=expires_in)
response = make_response(redirect('/home'))
response.set_cookie(
'session', session_cookie, expires=expires, httponly=True, secure=True)
return response
Then, on any 'protected route' I am basically getting the cookie 'session':
#app.route('/home', methods=['GET', 'POST'])
def home():
session_cookie = request.cookies.get('session')
# session_cookie always returning None
return render_template("index.html")
The problem is that when I sign in, get the token (from JS) and make the POST request, the request to /sessionLogin works great and I see the cookie 'session' in the response but any subsequent requests and by the way the redirect to /home does not include the cookie.
What I am missing here?
UPDATE (adding Ajax code):
firebase.auth().signInWithEmailAndPassword(email, pass)
.then(({user}) => {
return user.getIdToken().then((idToken) => {
console.log(user)
if (idToken) {
const csrfToken = getCookie('csrfToken')
return postIdTokenToSessionLogin('/sessionLogin', idToken, csrfToken)
.then(function() {
console.log('logged in.')
}, function(error) {
window.location.assign('/login');
})
}
})
})
const postIdTokenToSessionLogin = function(url, idToken, csrfToken) {
// POST to session login endpoint.
return $.ajax({
type:'POST',
url: url,
data: {idToken: idToken, csrfToken: csrfToken},
contentType: 'application/x-www-form-urlencoded'
});
};

Flask - get redirected to new page after POST-request

I have an edit-button on my Site, that will do a POST-Request and then I want to be redirected to new.html, that contains a form, that holds my POST data.
The POST request in my js-file:
async function onEditBtn() {
// find correct entry in schedule
const data = schedule.find(meeting => meeting.id == rowIdOfContextMenu);
rowIdOfContextMenu = -1;
const response = await fetch("editmeeting", {
method: 'POST',
body: data});
}
The receiving Flask-route:
#app.route('/editmeeting', methods=['POST'])
def edit():
data = request.get_json()
print(data)
return render_template('new.html', data)
POST request is succesful, but I am not getting redirected to new.html.
If I use window.location.href = "<route to my edit page>"; or window.location.replace(); on js side using the response I get from the POST request, my edit page won't get the POST-data.
EDIT:
What I was looking for was window.location.href with POST instead of GET.
I ended up using Flask's session object. Did a POST request to /editmeeting, saved the POST-data in a session object, then manually redirected my page to another route rendering new.html using window.location.href in my js-code, and used the data stored in the session.
Thank you for your aswers!
You could add GET method to this function
#app.route('/editmeeting', methods=['GET', 'POST']
or add this to your imports
from flask import Flask, redirect, url_for
and change the return of the function to something like this (only works when 'new' is indeed a function in your app.
return redirect(url_for('new'))

Decode JSON in flask

i want to send JSON format data in my flask app using AJAX call,
when i send it i got "None" in flask.
here is jquery,
$('#form').on('click',function(){
var text = $('#textField').val();
var obj = {name:text};
var myJSON = JSON.stringify(obj);
$.ajax({
data : myJSON,
url: '/process',
type : 'post',
contentType: 'application/json',
dataType : 'json'
})
})
here is my Flask route,
#app.route('/process',methods=["POST"])
def process():
data = request.json
return render_template("form.html",data = data)
in data i got "None".
return render_template is not fruitful as data is being sent via Ajax. It will return the template contents.
You can receive the data returned from Flask via done method in Ajax.
I am adding an example code to demonstrate how to handle Ajax submission with JSON data.
app.py:
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/process',methods=["GET", "POST"])
def process():
if request.method == 'POST':
data = request.json
return jsonify(data)
return render_template("form.html")
app.run(debug=True)
form.html:
<html>
<head>
<title>Form</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="data"></div>
<input type="text" id="textField" />
<button id="demo_btn">Dummy button</button>
<script>
$(document).ready(function () {
$("#demo_btn").on("click", function() {
var text = $('#textField').val();
var obj = {name:text};
var myJSON = JSON.stringify(obj);
$.ajax({
url: '/process',
type : 'post',
contentType: 'application/json',
dataType : 'json',
data : myJSON
}).done(function(result) {
$("#data").html(result["name"]);
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("fail: ",textStatus, errorThrown);
});
});
});
</script>
</body>
</html>
Output:
Reference:
http://api.jquery.com/jquery.ajax/
It looks like JQuery isn't setting the correct header.
If you use the request.get_json() method instead of the request.json property it will get json irrespective of the header.

Why does this Python Flask router return a 400 error when pinged by a crossdomain AJAX call?

I have the below Python Flask router:
#app.route('/create', methods=['GET', 'POST'])
#crossdomain(origin='*')
def create():
if request.method == 'POST':
print(request.form)
title = request.form['title']
url = request.form['url']
new_mark = Mark(
title=title,
url=url
)
new_mark.save()
return new_mark
When I do an ajax call (below) it responds with a 400 error.
$.ajax({
type: 'POST',
url: 'http://localhost:5000/create',
data: {
'title': sender.title,
'url': sender.url
},
xhrFields: {
withCredentials: true
},
dataType: 'json'
});
When I try printing out request it prints an empty immutableMultiDict. Any idea why it is giving this 400 and why there is no data?
Your ajax call is sending json-encoded data. I guess you should decode.
import json
data = json.loads(request.data)
print data.get("title")
I am stupid. I was not actually sending any data because sender.url and sender.title did not contain any values -_-.

Send data from a textbox into Flask?

I was wondering if there was a way to take something from a text box in the HTML, feed it into flask, then parse that data with Python. I was thinking this might involve some JS but I could be wrong. Any ideas?
Unless you want to do something more complicated, feeding data from a HTML form into Flask is pretty easy.
Create a view that accepts a POST request (my_form_post).
Access the form elements in the dictionary request.form.
templates/my-form.html:
<form method="POST">
<input name="text">
<input type="submit">
</form>
from flask import Flask, request, render_template
app = Flask(__name__)
#app.route('/')
def my_form():
return render_template('my-form.html')
#app.route('/', methods=['POST'])
def my_form_post():
text = request.form['text']
processed_text = text.upper()
return processed_text
This is the Flask documentation about accessing request data.
If you need more complicated forms that need validation then you can take a look at WTForms and how to integrate them with Flask.
Note: unless you have any other restrictions, you don't really need JavaScript at all to send your data (although you can use it).
Declare a Flask endpoint to accept POST input type and then do necessary steps. Use jQuery to post the data.
from flask import request
#app.route('/parse_data', methods=['GET', 'POST'])
def parse_data(data):
if request.method == "POST":
#perform action here
var value = $('.textbox').val();
$.ajax({
type: 'POST',
url: "{{ url_for('parse_data') }}",
data: JSON.stringify(value),
contentType: 'application/json',
success: function(data){
// do something with the received data
}
});
All interaction between server(your flask app) and client(browser) going by request and response. When user hit button submit in your form his browser send request with this form to your server (flask app), and you can get content of the form like:
request.args.get('form_name')
Assuming you already know how to write a view in Flask that responds to a url, create one that reads the request.post data. To add the input box to this post data create a form on your page with the text box. You can then use jquery to do
var data = $('#<form-id>').serialize()
and then post to your view asynchronously using something like the below.
$.post('<your view url>', function(data) {
$('.result').html(data);
});
This worked for me.
def parse_data():
if request.method == "POST":
data = request.get_json()
print(data['answers'])
return render_template('output.html', data=data)
$.ajax({
type: 'POST',
url: "/parse_data",
data: JSON.stringify({values}),
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function(data){
// do something with the received data
}
});

Categories