I am trying XHR GET request on a python-flask based API and getting this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://..... (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
The server code:
from flask_restful import Api
from flask_cors import CORS
application_root = config.get_application_root()
static_folder = os.path.join(application_root, 'static')
template_folder = os.path.join(application_root, 'templates')
app = Flask(__name__, static_url_path='/static', static_folder=static_folder, template_folder=template_folder)
cors = CORS(app)
app.config['SQLALCHEMY_DATABASE_URI'] ='mysql://*********'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['PROPAGATE_EXCEPTIONS'] = True # To allow flask propagating exception even if debug is set to false on app^M
api = Api(app)
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
return response
api.add_resource(TestResults, '/results')
if __name__ == '__main__':
db.init_app(app)
app.run(host='0.0.0.0', debug=True) # important to mention debug=True^M
The response header still doesn't get the required header.
Content-Length 2452
Content-Type application/json
Date Tue, 06 Nov 2018 06:52:06 GMT
Server Werkzeug/0.14.1 Python/3.4.7
What am I missing here...
Related
I want to get response using Flask from OpenAI API. Whether I am getting Status 400 Bad Request from Browser through http://127.0.0.1:5000/chat
Bad Request
The browser (or proxy) sent a request that this server could not understand.
Also I am checking this from Postman
from flask import Flask, request, render_template
import requests
app = Flask(__name__)
#app.route('/')
def index():
return 'Welcome to ChatGPT app!'
#app.route('/chat', methods=['GET', 'POST'])
def chat():
user_input = request.form['text']
# Use OpenAI's API to generate a response from ChatGPT
response = generate_response_from_chatgpt(user_input)
return response
def generate_response_from_chatgpt(user_input):
api_key = "YOUR_API_KEY"
url = "https://api.openai.com/v1/engines/davinci/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
data = {
"prompt": user_input,
"engine": "davinci"
}
response = requests.post(url, headers=headers, json=data)
return response.json()["choices"][0]["text"]
if __name__ == '__main__':
app.run()
It would be best if you check the openai documentation to make sure you are using the correct endpoint and data format in your request.
Also, you should check your API key, if it is correct and if you have reached the limit of requests.
Also, it's worth noting that the code you provided is missing the import statement for Flask. You will need to add the following line at the top of your file:
from flask import Flask, request
Also, I see that you're using request.form['text'] but you should check if the request is a GET or POST request.
if request.method == 'POST':
user_input = request.form['text']
else:
user_input = request.args.get('text')
This is to avoid a KeyError being raised when the request is a GET request.
With Ionic Angular running in on my localhost I made this call to my Django backend (running on different localhost):
test() {
return this.httpClient.get(endpoint + '/test', {
headers: { mode: 'no-cors' },
});
}
And on the backend side I have following code to respond:
#csrf_exempt
def test(request):
response = json.dumps({'success': True})
return HttpResponse(response, content_type='application/json', headers={'Access-Control-Allow-Origin': '*'})
I have also this in my settings.py file:
INSTALLED_APPS = [
...
'corsheaders',
]
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
]
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
Still, I get this error message in my console:
Access to XMLHttpRequest at 'http://127.0.0.1:8000/test' from origin 'http://localhost:8100' has been blocked by CORS policy: Request header field mode is not allowed by Access-Control-Allow-Headers in preflight response.
What am I doing wrong?
You need to just add one more setting
CORS_ALLOW_ALL_HEADERS=True
Other than the above you do not need to set a header on each response. Just simply respond back with payload as
#csrf_exempt
def test(request):
response = json.dumps({'success': True})
return HttpResponse(response, content_type='application/json', headers={'Access-Control-Allow-Origin': '*'})
I have a Flask app with the following:
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
#app.after_request
def add_headers(response):
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Headers'] = "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
response.headers['Access-Control-Allow-Methods']= "POST, GET, PUT, DELETE, OPTIONS"
return response
# some stuff
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
But I still get CORS error in the browser. I am running the app on Gitpod. If I set the port to public it works fine, but I shouldn't have to have a publicly available API endpoint just to get this working on the same server.
If using javascript fetch, fetch does not include credentials by default, you should do fetch("<Your URL>", { credentials: 'include' })
I have tried several things but I am not able to figure this one out. I have a back-end flask app and a front-end client written in Angular. When I submit my register user form I get a cors error. I have read the documentation for flask_cors and have tried to get it to work but I still get the same error below:
Access to XMLHttpRequest at 'http://localhost:5000/v1/auth/register' from origin 'http://localhost:4200' 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.
Here is my app.py from the flask app.
Any help is greatly appreciated!
import os, sys
from flask import Flask
import pathlib
from flask_cors import CORS
from flask_restplus import Api, Resource, fields
from werkzeug.middleware.proxy_fix import ProxyFix
import coloredlogs, logging as log
coloredlogs.install()
from main.apis.user import api as User
from main.apis.auth import api as Auth
from main import create_app
from flask_pymongo import PyMongo
# Init app
app = Flask(__name__)
#cors = CORS(app, resources={r"*": {"origins": "*"}})
CORS(app, origins="http://localhost:4200", allow_headers=[
"Content-Type", "Authorization", "Access-Control-Allow-Credentials","Access-Control-Allow-Origin"],
supports_credentials=True, intercept_exceptions=False)
authorizations = {
'token': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
}
}
config_name = os.getenv('FLASK_CONFIG')
app = create_app(config_name)
api = Api(app, authorizations=authorizations, version='1.0', title='API docs',
description='A simple REST API with JWT authentication.',
doc='/docs'
)
app.config['jwt']._set_error_handler_callbacks(api)
app.config['ROOT_DIR'] = pathlib.Path(__file__).parent.absolute()
# #app.before_first_request
# this function is to init the db and realted models
# def create_tables():
# print("Before first statement")
# db.create_all()
# Endpoints
api.add_namespace(Auth, path='/v1')
api.add_namespace(User, path='/v1')
# Run Server
if __name__ == '__main__':
app.run()
adding this seemed to fix my issue.
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
return response
Looks like in your code you are creating app = Flask(__name__), applying the CORS to that variable and then over writing app by using app = create_app(config_name) a few lines later. So that causes your CORS setup on the first app to be lost.
I have set up a server with flask CORS and had it working for sending data to a React web app that I built, but when I went to test the POST method it stoped working and now it is broken for sending and receiving. The error log in the console of the web app is: "Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Fetch API cannot load http://127.0.0.1:5000/ due to access control checks. "
I ran into this issue earlier and added flask_cors and it worked for a while. Here is my server code:
from flask_cors import CORS, cross_origin
app = FlaskAPI(__name__)
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
app.config['CORS_HEADERS'] = 'Content-Type'
cors = CORS(app, resources={r"/": {"origins": "http://localhost:port"}})
# Also fails with this variation
# cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
#app.route("/", methods=['GET', 'POST'])
#cross_origin(origin='localhost',headers=['Content- Type','Authorization'])
# Also fails with these variations
# #cross_origin(origin='http://127.0.0.1:5000/',headers=['Content- Type','Authorization'])
# #cross_origin(origin='http://localhost:3000',headers=['Content- Type','Authorization'])
def job_api():
with app.app_context():
job_data = get_job_data()
json_data = jsonify(eqtls=[job.data for job in job_data])
return json_data
if __name__ == "__main__":
app.run(debug=True)
Here is my client code:
componentDidMount() {
fetch('http://127.0.0.1:5000/')
.then(res => res.json())
.then((data) => {
this.setState({ job_data: data.eqtls })
})
.catch(console.log)
}
You need to enable CORS policy on your API, so it can accept requests from across different hosts.
Just do a google Flask cors, and make sure you are Accepting '*' or specifically your URL.
If you accept cors though you should be able to accept all CORS and then make your API robust enough so that no nasty data can be requested
Try:
from flask_cors import CORS, cross_origin
app = FlaskAPI(__name__)
app.config['SECRET_KEY'] = 'the quick brown fox jumps over the lazy dog'
app.config['CORS_HEADERS'] = 'Content-Type'
#app.route("/", methods=['GET', 'POST'])
#cross_origin()
def job_api():
with app.app_context():
job_data = get_job_data()
json_data = jsonify(eqtls=[job.data for job in job_data])
return json_data
if __name__ == "__main__":
app.run(debug=True)
I read the documenttation, and can just add #cross_origin() as a simple decorator: https://flask-cors.readthedocs.io/en/latest/#route-specific-cors-via-decorator