1
votes

I'm using Flask to build a simple backoffice. I'm trying to make some requests on client-side using AJAX, but it is always throwing me the following error:

access to XMLHttpRequest at 'http://10.11.0.123/...' from origin 'http://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I've already tried several solutions but none of them worked. I'm also using CORS package from flask_cors, in the following way:

    CORS(app, resources={r"/hardware/control/1": {"origins": "http://localhost:5000"}})
    app.run(host="0.0.0.0", port=5000, threaded=True)

However, I think that have no impact on AJAX requests since Flask app runs on server side. So here it is my ajax request:

$.ajax({
            url: 'http://10.11.0.123/...',
            type: "GET",
            contentType: 'text/plain',
            headers: {
                'Access-Control-Allow-Origin': '*',
            },
            withCredentials: true,
            crossDomain: true,
            success: function (result) {
                console.log(result)
            },
        });

I know that the destination sever is receiving the request, however I can not receive any response from the server.

Analysing the network requests, from chrome console, the request returns status: failed and Type: xhr.

My endpoint in flask is:

@system.route('/hardware/control/<int:device_id>')
def hardware_control(device_id):
    device = Device.query.get(device_id)
    return render_template('hardware_interaction/camera_preview.html',device=device)

I'm creating the app like this:

def create_app():
     app = Flask(__name__, instance_relative_config=False)
     app.config.from_object('config.DevelopmentConfig')
     CORS(app, resources={r"/hardware/control/*": {"origins": "*"}})
     with app.app_context():
        return app

app = create_app()

if __name__ == "__main__":
     app.run(host="0.0.0.0", port=5000, threaded=True)
3
instead of "origins": "http://localhost:5000" try "origins": "*" and make sure you're hitting the endpoint specified in the resources property. As the one sparse answer mentioned, the issue is that your server needs to have an Access-Control-Allow-Origin header set that will be returned in what is called a "preflight" or "options" request. As always, I recommend reading documentation: developer.mozilla.org/en-US/docs/Web/HTTP/CORSRobbie Milejczak
Thank you for the response. It does not work. I've already tried it.Miguel Andrade

3 Answers

2
votes

You can use this to test that it's actually a CORS issue. This worked for me.

@app.after_request
def after_request(response):
    header = response.headers
    header['Access-Control-Allow-Origin'] = '*'
    header['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
    header['Access-Control-Allow-Methods'] = 'OPTIONS, HEAD, GET, POST, DELETE, PUT'
    return response
0
votes

The header Access-Control-Allow-Origin must be returned from Flask, not requested by AJAX. So it would be something like this:

def get_content():
    return "It works!", 200

@app.route('/')
def home():
    content, status_code = get_content()
    headers = {'Access-Control-Allow-Origin': '*'}
    return content, status_code, headers
0
votes

Thank you all for the help. I already solved the problem. I was making requests to HTTP PTZ Camera which don't let me make requests from client side (I've no idea why). So I hack the problem, and now I'm making requests to my server, and my server make the request to the camera. Here you've what I'm doing:

$.ajax({url: 'http://127.0.0.1:5000/teste00',
        type: "GET",
        success: function (result) {},
        });

On server side:

@system.route('/teste00')
def teste():
    response = requests.get('camera_url')
   return response.content