POST request gets blocked on Python backend. GET request works fine

Question:

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 and CORS 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.

Asked By: Abdallah Ibrahim

||

Answers:

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!

Answered By: c8999c 3f964f64

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 the

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:
enter image description here

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.
enter image description here
It was just this CORS blocking the response completely that made me handi-capped.

Answered By: Abdallah Ibrahim

Add below line to your header map

{
"….":"…."
"Accept": "/"
.
.
.
}

Answered By: Asif Akhtar98
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.