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?
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.
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
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)
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
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)
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.
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__)
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
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)
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)
©2020 All rights reserved.