Reputation: 3452
I am kind of new to Python, but I have had the same issue working with Node apps. I am making a pretty standard jQuery AJAX request to my local Python sever:
init: function(callback) {
var token = _config.get_token();
$.ajax({
url: 'http://localhost:5000/api/ia/v1/user_likes',
type: 'POST',
contentType: 'application/json',
datatype: 'json',
data: token
})
.done(function(data) {
callback(data);
})
.fail(function(err) {
callback(err);
});
callback(token);
}
I can confirm that the variable token is confirming like this:
Object {access_token: "791415154.2c0a5f7.4d707361de394512a29682f9cb2d2846", campaign_id: "102"}
But I am getting this error from my javascript console:
XMLHttpRequest cannot load http://localhost:5000/api/ia/v1/user_likes. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://s3.amazonaws.com' is therefore not allowed access. The response had HTTP status code 500.
I have found that when I am building Node apps that this is a cors error. The page that I am running the jQuery AJAX request from is http. Here are the parts of my Python code that I believe I am configuring incorrectly:
from flask import Flask, request, redirect
from flask.ext.cors import CORS, cross_origin
app = Flask(__name__)
cors = CORS(app)
app.config['CORS_HEADERS'] = 'application/json'
And the route:
@app.route("/api/ia/v1/user_likes", methods=['POST', 'OPTIONS'])
def user_likes():
validate = validate_request(request.data)
return 'something'
My Python error is also returning an error because the request is never making it to this line of code:
def validate_request(object_from_user):
load_object = json.loads(object_from_user)
I can fix that later. Anyway, does anyone have any suggestions for Cors configurations for Python?
Upvotes: 34
Views: 154828
Reputation: 117
I basically followed @david and it worked well for me, here is how i returned my response
first i installed flask-cors
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app, support_credentials=True)
used it on my endpoint
@cross_origin() # added this to my endpoint
@app.route('/api/verify-authenticity', methods=['POST'])
def verify_image():
then returned my response with the following headers
return Response(
response,
headers={
"Content-Type": "application/json",
"Access-Control-Allow-Origin": '*',
"Access-Control-Allow-Methods": 'PUT, GET, POST, DELETE, OPTIONS',
"Access-Control-Allow-Headers": 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
},
content_type='application/json'
)
Upvotes: 2
Reputation: 1766
Please note that if your application returns a 500 error your browser may understand it as a cors error as flask cors only adds headers on return.
So, if the other options don't work you can put your flask in debug mode to validate if it's not just an internal server error.
.flaskenv
FLASK_ENV=development
Upvotes: 1
Reputation: 61
I tried all of the above solutions and they kept failing for me. I am sure, most solutions would have worked, but there was one very obvious mistake I made in my client application. Maybe this saves some of you a bit of debugging time. I my request, I called my REST-service via
'localhost:<port>/<myApi>'
The fix for me was as simple as calling the service as http... :
'http://localhost:<port>/<myApi>'
A silly mistake.
Upvotes: 5
Reputation: 116
I have installed flask using the following command and using the declaration like this:
pips3.6 install --user flask-cors
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
Upvotes: -2
Reputation: 1764
On client side you only need to ensure that kind of data your server is dealing with. For example form data or json.
For me the code written below did magic
from flask import Flask,request,jsonify
from flask_cors import CORS,cross_origin
app=Flask(__name__)
CORS(app, support_credentials=True)
@app.route('/api/test', methods=['POST', 'GET','OPTIONS'])
@cross_origin(supports_credentials=True)
def index():
if(request.method=='POST'):
some_json=request.get_json()
return jsonify({"key":some_json})
else:
return jsonify({"GET":"GET"})
if __name__=="__main__":
app.run(host='0.0.0.0', port=5000)
Upvotes: 1
Reputation: 153
Based on GyuHyeon Choi's response, but with added return response
and an extra Access-Control-Expose-Headers
worked for me.
@app.after_request
def add_headers(response):
response.headers.add('Content-Type', 'application/json')
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Expose-Headers', 'Content-Type,Content-Length,Authorization,X-Pagination')
return response
Upvotes: 0
Reputation: 1578
Please use @cross_origin(origin='*') in your python file
from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
@app.route("/login", methods = ['GET'])
@cross_origin(origin='*')
def login():
return jsonify({'success': 'ok'})
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000, debug=True)
Upvotes: 8
Reputation: 4095
After I tried others suggestions and answers. Here's what I use, which works.
Steps:
pip install flask flask-cors
Copy and paste this in app.py
file
Code
from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app, support_credentials=True)
@app.route("/login")
@cross_origin(supports_credentials=True)
def login():
return jsonify({'success': 'ok'})
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8000, debug=True)
python app.py
Note: be sure in your client's ajax configuration has the following:
$.ajaxSetup({
type: "POST",
data: {},
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true,
contentType: 'application/json; charset=utf-8'
});
If one wonders, support_credentials=True
just means it sends cookies along the payload back and forth.
Upvotes: 41
Reputation: 239
Flask has the flask-cors module. Following is the code snippet as well as the procedure.
pip install -U flask-cors
Add this lines in your flask application:
from flask import Flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello world"
See more by clicking on this link
Upvotes: 22
Reputation: 5156
Try this:
@app.after_request
def add_headers(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
I've tried @cross_origin tutorial on the Flask website,however, it did not work for me.
But it seems like you can add headers to your response later.
Here is my remaining code that I think it may be useful.
from flask import Flask, request
from sklearn.externals import joblib
app = Flask(__name__)
Upvotes: 1
Reputation: 1916
Here is how to get your hand dirty by handling the CORS detail all by yourself:
handle_result = {'result': True, 'msg': 'success'}
try:
# origin, where does this request come from, like www.amazon.com
origin = flask.request.environ['HTTP_ORIGIN']
except KeyError:
origin = None
# only accept CORS request from amazon.com
if origin and origin.find('.amazon.com') > -1:
resp = flask.make_response(str(handle_result))
resp.headers['Content-Type'] = 'application/json'
h = resp.headers
# prepare headers for CORS authentication
h['Access-Control-Allow-Origin'] = origin
h['Access-Control-Allow-Methods'] = 'GET'
h['Access-Control-Allow-Headers'] = 'X-Requested-With'
resp.headers = h
return resp
return flask.abort(403)
Upvotes: 7
Reputation: 91
The below solution worked for me. I included a method that will add the headers necessary for you and then raise the HTTP response. Ex:
def some_method(response_data, status_code):
response_data = //here you can manipulate the data, JSONify, convert arrays into objects or vice versa
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": '*',
"Access-Control-Allow-Methods": 'PUT, GET, POST, DELETE, OPTIONS',
"Access-Control-Allow-Headers": 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
}
//THEN RAISE HTTPResponse
raise HTTPResponse(status, headers, body)
Note: The above method is not python compiling so you may have to edit it.
Upvotes: 1
Reputation: 60
use the cors decorator after the route decorator.
here's a snippet from the documentation...
@app.route("/")
@cross_origin() # allow all origins all methods.
def helloWorld():
return "Hello, cross-origin-world!"
now, it appears you are using json, if that's the case, you should likely just read the documentation as it specifically mentions this use case, and what cors_headers to set... it's below the fold, but this documentation is well written and easy to understand.
http://flask-cors.readthedocs.org/en/latest/#using-json-with-cors
Upvotes: 4