POST request gets blocked on Python backend. GET request works fine
Solution 1
I finally figured out what was going on. First I disabled the same origin policy in chrome using this command: this is run clicking the start button in windows and typing this command directly..
chrome.exe --disable-site-isolation-trials --disable-web-security --user-data-dir="D:\anything"
This fired a separate chrome window that does not block cross-origin, we will call this the CORS free window. This allowed me to finally communicate with my python code and understand what is going on.
You can see that the chrome default setting were not even showing me anything related to the response, just showing a 500 code error.
I copied the localhost link and port and pasted them in my other CORS free chrome window The other CORS free chrome window showed helpful information:
It was a simple JSON decoding error! I went back to my flutter code and I changed the http post request, adding a jsonEncode
function on the post body:
http.Response response = await http.post(Uri.parse(url), body:jsonEncode(data), headers: header);
Now the post request returns a correct response on the default chrome settings. It was just this CORS blocking the response completely that made me handi-capped.
Solution 2
Flask has an @app.after_request
decorator, this helped me to ensure the headers get added, regardless of what happens in the route
@app.after_request
def add_cors_headers(resp):
resp.headers.add('Access-Control-Allow-Origin', '*')
resp.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
resp.headers.add('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
This solved the CORS issues in my case!
Abdallah Ibrahim
I develop mobile apps and websites on my free time using Python, php and SQL. I am also interested in scientific programming using python, I work on some signal processing projects with some of my friends making some research type codes for new mathematical algorithms.
Updated on January 04, 2023Comments
-
Abdallah Ibrahim over 1 year
I am building a web app where the front-end is done with Flutter while the back-end is with Python. GET requests work fine while POST requests get blocked because of CORS, I get this error message:
Access to XMLHttpRequest at 'http://127.0.0.1:8080/signal' from origin 'http://localhost:57765' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Below is my flutter function I used to send GET and POST requests:
Future<dynamic> sendResponse() async { final url = 'http://127.0.0.1:8080/signal'; var data = { "signal": '8', }; var header = { 'Access-Control-Allow-Origin': '*', "Accept": "application/x-www-form-urlencoded, '*'" }; http.Response response = await http.post(Uri.parse(url), body: data, headers: header);//http.post(Uri.parse(url), body: data, headers: header);//http.get(Uri.parse(url)); if (response.statusCode == 200) { print(json.decode(response.body)); return jsonDecode(response.body); //print(json.decode(credentials.body)); } else { print(response.statusCode); throw Exception('Failed to load Entry'); } // var ResponseFromPython = await response.body;//jsonDecode(credentials.body); // return ResponseFromPython; }
Below is my Python backend code using Flask:
from flask import Flask,jsonify, request, make_response import json from flask_cors import CORS, cross_origin #declared an empty variable for reassignment response = '' app = Flask(__name__) #CORS(app, resources={r"/signal": {"origins": "*, http://localhost:59001"}}) #http://localhost:52857 #CORS(app, origins=['*']) app.config['CORS_HEADERS'] = ['Content-Type','Authorization'] @app.route("/") def index(): return "Congratulations, it worked" @app.route("/signal", methods = ['POST', 'GET']) #, @cross_origin(origins='http://localhost:57765',headers=['Content-Type','Authorization', 'application/x-www-form-urlencoded','*'], upports_credentials=True)# allow all origins all methods. def multbytwo(): """multiple signal by 2 just to test.""" global response if (request.method=='POST'): # request.headers.add("Access-Control-Allow-Origin", "*") request_data = request.data #getting the response data request_data = json.loads(request_data.decode('utf-8')) #converting it from json to key value pair comingSignal = request_data['signal'] response = make_response(comingSignal, 201)#jsonify(comingSignal*2) response.headers.add('Access-Control-Allow-Origin', '*') response.headers.add('Access-Control-Allow-Methods", "DELETE, POST, GET, OPTIONS') response.headers.add('Access-Control-Allow-Headers", "Content-Type, Authorization, X- Requested-With') return response else: try: #scaler = request.args.get("signal") out = 9 * 2 response = jsonify(out) response.headers.add("Access-Control-Allow-Origin", "*") return response #sending data back to your frontend app except ValueError: return "invalid input xyz" if __name__ == "__main__": app.run(host="127.0.0.1", port=8080, debug=True)
Below are the troubleshooting steps I made: -Added the flask_CORS package in python I tried here different combination from using general parameters like
CORS(app, resources={r"/signal": {"origins": "*"}})
did not help. Also tried the decorator@cross-origin
and did not help-Added some headers to the response itself to indicate that it accepts cross-origin You see in my python code I tried adding a lot of headers to the response, nothing seem to respond.
-Tried installing an extension in Chrome that by-passes the CORS check I tried the
allow CORS
andCORS unblock
extensions and I used the steps described in this answer: How chrome extensions be enabled when flutter web debugging?. Although these extensions are supposed to add the CORS allow header to the response, I still got the same error.I still do not fully understand the CORS concept but I tried a lot of work-arounds and nothing works! please help.
-
Abdallah Ibrahim about 2 yearsThanks for the answer, can you clarify if there is a specific location in the code where this decorator should be placed? I tried to put it before and after my
@app.route
decorator but both did not work. Should I define a global variable called response and use it in both the response function and the@app.after_request
decorator? -
c8999c 3f964f64 about 2 yearsI have this in the same file that has the app.run function. The decorator makes sure that the function below it (add_cors_headers in this case) will be run after every request. You dont need a global variable "resp", that is given to that function by flask automatically