我有一个用 python/flask 编写的 API,我只想允许几个 URL 访问这个 API。JavaScript 调用是简单的 jQuery,例如:
$.ajax({
url: "http://myApi.com/api/doit",
dataType:'JSON',
success:function(data){
console.log("DEBUG: yeeeeaaaahhh!");
},
error:function(xhr){
console.log("Error occured! status: " + xhr.status + ", text: " + xhr.statusText);
}
});
Run Code Online (Sandbox Code Playgroud)
主要在这里的大多数解决方案都非常令人失望,总是提供设置Access-Control-Allow-Origin : '*'
或启动 chrome 禁用检查。当然它有效,但这不是目的。w3上的规范说分号分隔的列表应该有效,但事实并非如此。逗号分隔列表也失败。烧瓶本身有http://flask.pocoo.org/snippets/56/但它不适用于多个 URL。在评论中有一个建议:h.extend([("Access-Control-Allow-Origin", orig) for orig in origin])
但它仍然不起作用。
我唯一的解决方案是检查源代码,以防它在我的白名单中放入标题Access-Control-Allow-Origin : '*'
。这是一种解决方法,但我不太喜欢它。你能提出一个更优雅的解决方案吗?
这是在本地使用同一个前端项目的多个实例一起访问本地 Flask 服务器时的典型场景,并且由于您允许凭据(即使用 JWT 身份验证)而不允许使用通配符“*”。
我的方法 - 在开发中 - 是使用after_request装饰器和 Flask 的请求上下文。
创建域白名单:
white = ['http://localhost:8080','http://localhost:9000']
Run Code Online (Sandbox Code Playgroud)
现在使用after_request
装饰器拦截所有传入的请求,检查引用者是否在您的白名单中,如果是,则注入response.headers
以允许访问源。例如:
from flask import request
@app.after_request
def add_cors_headers(response):
r = request.referrer[:-1]
if r in white:
response.headers.add('Access-Control-Allow-Origin', r)
response.headers.add('Access-Control-Allow-Credentials', 'true')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
response.headers.add('Access-Control-Allow-Headers', 'Cache-Control')
response.headers.add('Access-Control-Allow-Headers', 'X-Requested-With')
response.headers.add('Access-Control-Allow-Headers', 'Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
return response
Run Code Online (Sandbox Code Playgroud)
简单的例子,试试吧!
我希望它能帮助你。您需要编辑“Access-Control-Allow-Origin”的white_origin。
app_name.py(Flask的Python文件)
from flask import request
@app.after_request
def after_request(response):
white_origin= ['https://www.dom.com','http://localhost:8000']
if request.headers['Origin'] in white_origin:
response.headers['Access-Control-Allow-Origin'] = request.headers['Origin']
response.headers['Access-Control-Allow-Methods'] = 'PUT,GET,POST,DELETE'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization'
return response
Run Code Online (Sandbox Code Playgroud)