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

257

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

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!

Share:
257
Abdallah Ibrahim
Author by

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, 2023

Comments

  • Abdallah Ibrahim
    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 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.

  • Abdallah Ibrahim
    Abdallah Ibrahim about 2 years
    Thanks 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
    c8999c 3f964f64 about 2 years
    I 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