简体   繁体   中英

Python Flask CORS - No 'Access-Control-Allow-Origin' header is present on the requested resource

I have a simple Ajax script written on a Shopify Product Page. This script would be triggered and send a json message to the API server whenever the upload button is clicked

 jQuery.ajax({
            url: "https://e20e2287e2cb.ngrok.io/return_json",
            type: "POST",
            data: form_data,
            processData: false,
            contentType: false,
            contentType: "application/json",
            success: function (result) {
              var obj = jQuery.parseJSON( result );
                jQuery(".select-loader").remove(); 
                jQuery("body").removeClass('active-loader');
                jQuery("#upload_image").removeClass("err");
                jQuery("#upload_image").val("");
                jQuery("#google_folder_id").val(obj.imguniquename);
                jQuery("#customImage").val(obj.imgname);
                jQuery("#customImageUrl").val(obj.folder_id);
                jQuery("#customUniqueImage").val(obj.imguniquename);
                
                jQuery("#upload_image").after('<p class="note note--success">Image uploaded successfully.</p>');
                Cookies.set('google_folder_id', obj.imguniquename);
                Cookies.set('customImage', obj.imgname);
                Cookies.set('customImageUrl', obj.folder_id);
                Cookies.set('customUniqueImage', obj.imguniquename);

            }
          });

In the API server, I have the following code written in Python:

#Flask Library
from flask import Flask, request, jsonify
from flask_cors import CORS, cross_origin
from flask_ngrok import run_with_ngrok

app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
logging.getLogger('flask_cors').level = logging.DEBUG
CORS(app)
run_with_ngrok(app) 

@app.route("/return_json", methods=["POST"])
def returnJson():
    return jsonify({'folder_id':'yoyo', 'img':'adad', 'imgname':'bibi', 'imguniquename':'kaka'})

if __name__ == '__main__':
    app.run()

Can anyone tell me why I would have the following errors in the browser console whenever the Ajax script is triggered?

  1. Access to XMLHttpRequest at 'https://e20e2287e2cb.ngrok.io/return_json' from origin 'https://www.abcabc.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  2. POST https://e20e2287e2cb.ngrok.io/return_json net::ERR_FAILED

Meanwhile, on the API server end, the debug log looks fine to me as follow:

DEBUG: flask_cors.extension:Request to '/return_json' matches CORS resource '/ '. Using options: {'origins': ['. '], 'methods': 'DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT', 'allow_headers': ['. '], 'expose_headers': None, 'supports_credentials': False, 'max_age': None, 'send_wildcard': False, 'automatic_options': True, 'vary_header': True, 'resources': '/ ', 'intercept_exceptions': True, 'always_send': True}

DEBUG: flask_cors.core:CORS request received with 'Origin' https://www.abcabc.com

DEBUG: flask_cors.core:The request's Origin header matches. Sending CORS headers.

DEBUG: flask_cors.core:Settings CORS headers: MultiDict([('Access-Control-Allow-Origin', 'https://www.abcabc.com'), ('Vary', 'Origin')]) INFO:werkzeug:127.0.0.1 - - [23/Apr/2021 11:04:44] "POST /return_json HTTP/1.1" 200 -

Since I haven't noticed you're already using Flask-CORS I'm updating this answer with some further investigations.

I've fired up a testing environment and managed to make this cross-origin request work properly without changing your code. During this process, I came up with the following possible reasons for your issue:

  1. Be sure to request an existing tunnel endpoint. Fetching closed NGROK tunnel endpoints result in CORS error, it does not raise a 404. To be sure I'm requesting the correct tunnel I wrote an index view route that just returns success. I also used this endpoint to ensure the CORS was properly set for all HTTP methods (GET, POST...);
  2. Be sure to import logging, Flask can lazy evaluate apps and raise exceptions only in request time. Check out your console for tracebacks;
  3. In Flask, if an exception occurs during a request, the request handling flow is aborted and Flask-CORS will never be called to add it's headers in the response object, and your browser will always complain about 'Access-Control-Allow-Origin'. That's why you should always check your browser's 'Response Tab', it may contain a traceback or some other useful information;
  4. Check for some info in NGROK introspect accessing http://localhost:4040/, it may help you track many issues;
  5. I faced some issues running flask-ngrok provided through pip. I've downloaded its source code from GitHub and imported it into my demo app. Frankly, I would ditch this extension and just run $ ngrok http 5000 in another console;
  6. Be sure to set FLASK_DEBUG=true or it may hide some info/tracebacks from you.

Check this Gist for the source code I've used and some evidence: https://gist.github.com/magnunleno/8dad91f133a22322250d6cb609792597

If you find any new info or traceback, please let me know so we can work out a solution.

Old Answer

That happens when you run your server under a specific domain (in your case e20e2287e2cb.ngrok.io) but your web client runs in a different domain (suppose www.abcabc.com ) and they try to communicate. You should really take a look at this .

This behavior can be configured by managing your app headers Access-Control-* and, luckily, there is a nice extension that does that for you called Flask-CORS .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM