Python Javascript - 请求的资源上不存在“Access-Control-Allow-Origin”标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22181384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript - No 'Access-Control-Allow-Origin' header is present on the requested resource
提问by Jaroslav Klim?ík
I need to send data through XmlHttpRequestfrom JavaScript to Python server. Because I'm using localhost, I need to use CORS. I'm using the Flask framework and its module flask_cors.
我需要将数据XmlHttpRequest从 JavaScript发送到 Python 服务器。因为我使用的是 localhost,所以我需要使用CORS。我正在使用 Flask 框架及其模块flask_cors。
As JavaScript I have this:
作为 JavaScript 我有这个:
var xmlhttp;
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("POST", "http://localhost:5000/signin", true);
var params = "email=" + email + "&password=" + password;
xmlhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseText);
}
}
xmlhttp.send(params);
and Python code:
和Python代码:
@app.route('/signin', methods=['POST'])
@cross_origin()
def sign_in():
email = cgi.escape(request.values["email"])
password = cgi.escape(request.values["password"])
But when I execute it I get this message:
但是当我执行它时,我收到以下消息:
XMLHttpRequest cannot load localhost:5000/signin. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
XMLHttpRequest 无法加载 localhost:5000/signin。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'null'。
How should I fix it? I know that I need to use some "Access-Control-Allow-Origin" header but I don't know how to implement it in this code. By the way I need to use pure JavaScript.
我该如何解决?我知道我需要使用一些“Access-Control-Allow-Origin”标头,但我不知道如何在这段代码中实现它。顺便说一句,我需要使用纯 JavaScript。
采纳答案by Zachary Jacobi
I got Javascript working with Flask by using this decorator, and adding "OPTIONS" to my list of acceptable methods. The decorator should be used beneath your route decorator, like this:
我通过使用这个装饰器让 Javascript 与 Flask 一起工作,并将“OPTIONS”添加到我可接受的方法列表中。装饰器应该在你的路由装饰器下面使用,像这样:
@app.route('/login', methods=['POST', 'OPTIONS'])
@crossdomain(origin='*')
def login()
...
Edit:Link appears to be broken. Here's the decorator I used.
编辑:链接似乎已损坏。这是我使用的装饰器。
from datetime import timedelta
from flask import make_response, request, current_app
from functools import update_wrapper
def crossdomain(origin=None, methods=None, headers=None, max_age=21600,
attach_to_all=True, automatic_options=True):
"""Decorator function that allows crossdomain requests.
Courtesy of
https://blog.skyred.fi/articles/better-crossdomain-snippet-for-flask.html
"""
if methods is not None:
methods = ', '.join(sorted(x.upper() for x in methods))
# use str instead of basestring if using Python 3.x
if headers is not None and not isinstance(headers, basestring):
headers = ', '.join(x.upper() for x in headers)
# use str instead of basestring if using Python 3.x
if not isinstance(origin, basestring):
origin = ', '.join(origin)
if isinstance(max_age, timedelta):
max_age = max_age.total_seconds()
def get_methods():
""" Determines which methods are allowed
"""
if methods is not None:
return methods
options_resp = current_app.make_default_options_response()
return options_resp.headers['allow']
def decorator(f):
"""The decorator function
"""
def wrapped_function(*args, **kwargs):
"""Caries out the actual cross domain code
"""
if automatic_options and request.method == 'OPTIONS':
resp = current_app.make_default_options_response()
else:
resp = make_response(f(*args, **kwargs))
if not attach_to_all and request.method != 'OPTIONS':
return resp
h = resp.headers
h['Access-Control-Allow-Origin'] = origin
h['Access-Control-Allow-Methods'] = get_methods()
h['Access-Control-Max-Age'] = str(max_age)
h['Access-Control-Allow-Credentials'] = 'true'
h['Access-Control-Allow-Headers'] = \
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
if headers is not None:
h['Access-Control-Allow-Headers'] = headers
return resp
f.provide_automatic_options = False
return update_wrapper(wrapped_function, f)
return decorator
回答by Oscar Paz
The Access-Control-Allow-Originmust be sent by the server, not by you. When you make a call to another domain, the browser checks whether this header is returned by the server. If it isn't, the call fails. I don't know Python, so I don't know how to make your server send this header, or even if you can modify the server at all.
该访问控制允许来源必须由服务器发送,而不是你。当您调用另一个域时,浏览器会检查此标头是否由服务器返回。如果不是,则调用失败。我不懂 Python,所以我不知道如何让你的服务器发送这个标头,甚至你根本不知道你可以修改服务器。
回答by boxmein
There's actually a brilliant snippet on the Flask site to modify the Access-Control-Allow-Originheader server-side. http://flask.pocoo.org/snippets/56/
Flask 站点上实际上有一个很棒的片段来修改Access-Control-Allow-Origin头服务器端。http://flask.pocoo.org/snippets/56/
You have the easy way out from there, which is to allow every *domain to access your URL, or specifying your selection of URLs inside the header.
你有一个简单的方法,那就是允许每个*域访问你的 URL,或者在标题中指定你选择的 URL。
From the MDN's article on CORS:
In this case, the server responds with a
Access-Control-Allow-Origin: *which means that the resource can be accessed by any domain in a cross-site manner. If the resource owners at http://bar.otherwished to restrict access to the resource to be only from http://foo.example, they would send back:Access-Control-Allow-Origin: http://foo.example.
在这种情况下,服务器以 a 响应,
Access-Control-Allow-Origin: *这意味着该资源可以被任何域以跨站点方式访问。如果http://bar.other的资源所有者 希望限制对资源的访问只能来自 http://foo.example,他们会发回:Access-Control-Allow-Origin: http://foo.example。
回答by campervancoder
I have used the flask-corsextension.
我使用了flask-cors扩展。
Install using pip install flask-cors
安装使用 pip install flask-cors
Then it's simply
那么就简单了
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
This will allow all domains
这将允许所有域
回答by Vikas
I have used the solution from Zachary. Works well.
我使用了 Zachary 的解决方案。效果很好。
For those who are wondering where to place the new decorator:
对于那些想知道在哪里放置新装饰器的人:
Just copy the code from the link that Zachary provided and place it in a .pyfile
只需从 Zachary 提供的链接中复制代码并将其放入.py文件中
Place it in the folder where your python modules are present(varies based on what system you use and whether or not you are using a virtual environment).
将它放在你的 python 模块所在的文件夹中(根据你使用的系统以及你是否使用虚拟环境而有所不同)。
In your flask app, import the method crossdomainfrom the newly created python module and use it.
在您的flask 应用程序中,crossdomain从新创建的python 模块导入方法并使用它。
回答by Luc Gendrot
Old question, but for future googlers with this problem, I solved it (and a few other downstream issues having to do with CORS) for my flask-restful app by adding the following to my app.py file:
老问题,但对于未来遇到此问题的谷歌用户,我通过将以下内容添加到我的 app.py 文件中,为我的 Flask-restful 应用解决了这个问题(以及其他一些与 CORS 相关的下游问题):
app = Flask(__name__)
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,OPTIONS')
return response
if __name__ == '__main__':
app.run()
回答by Alok Patra
When using python 2.7
使用 python 2.7 时
app = Flask(__name__)
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,OPTIONS')
return response
if __name__ == '__main__':
app.run()
When running on python3 or ahead,
install flask-cors using the command pip install flask-corsThe add the following:
在 python3 或之前运行时,使用命令安装flask-corspip install flask-cors添加以下内容:
from flask_cors import CORS
app = Flask(__name__)
CORS(app)

