Javascript - 请求的资源上没有“Access-Control-Allow-Origin”标头
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript - 请求的资源上没有“Access-Control-Allow-Origin”标头相关的知识,希望对你有一定的参考价值。
我需要通过XmlHttpRequest
从javascript向Python服务器发送数据。因为我正在使用localhost,所以我需要使用CORS。我正在使用Flask框架及其模块flask_cors
。
作为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);
和Python代码:
@app.route('/signin', methods=['POST'])
@cross_origin()
def sign_in():
email = cgi.escape(request.values["email"])
password = cgi.escape(request.values["password"])
但是当我执行它时,我得到了这样的信息:
XMLHttpRequest无法加载localhost:5000 / signin。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许原点'null'访问。
我该如何解决?我知道我需要使用一些“Access-Control-Allow-Origin”标头,但我不知道如何在此代码中实现它。顺便说一下,我需要使用纯JavaScript。
我使用这个decorator让Javascript与Flask一起工作,并在我可接受的方法列表中添加“OPTIONS”。应该在路径装饰器下面使用装饰器,如下所示:
@app.route('/login', methods=['POST', 'OPTIONS'])
@crossdomain(origin='*')
def login()
...
编辑:链接似乎已损坏。这是我用的装饰器。
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
我使用了烧瓶扩展。
使用pip install flask-cors
安装
那就简单了
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
这将允许所有域
老问题,但对于有这个问题的未来googlers,我通过将以下内容添加到我的app.py文件中来解决它(以及与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()
使用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()
在python3或者前面运行时,使用命令pip install flask-cors
安装flask-cors添加以下内容:
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
在Flask网站上实际上有一个很棒的片段来修改Access-Control-Allow-Origin
头服务器端。 http://flask.pocoo.org/snippets/56/
您可以轻松地从那里开始,即允许每个*
域访问您的URL,或指定您在标题内选择的URL。
在这种情况下,服务器使用
Access-Control-Allow-Origin: *
进行响应,这意味着任何域都可以跨站点方式访问资源。如果http://bar.other的资源所有者希望限制只能从http://foo.example访问资源,他们会发回:Access-Control-Allow-Origin: http://foo.example
。
我使用了Zachary的解决方案。效果很好。
对于那些想知道放置新装饰器的人:
只需复制Zachary提供的链接中的代码,并将其放在.py
文件中
将它放在python模块所在的文件夹中(根据您使用的系统以及您是否使用虚拟环境而有所不同)。
在您的烧瓶应用程序中,从新创建的python模块导入方法crossdomain
并使用它。
Access-Control-Allow-Origin必须由服务器发送,而不是由您发送。当您调用另一个域时,浏览器会检查服务器是否返回此标头。如果不是,则呼叫失败。我不知道Python,所以我不知道如何让你的服务器发送这个标题,或者即使你可以修改服务器。
以上是关于Javascript - 请求的资源上没有“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 JavaScript 代码会收到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”错误,而 Postman 却没有?
为啥我的 JavaScript 代码会收到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”错误,而 Postman 却没有?
为啥我的 JavaScript 代码会收到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”错误,而 Postman 却没有?
为啥我的 JavaScript 代码会收到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”错误,而 Postman 却没有?
为啥我的 JavaScript 代码会收到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”错误,而 Postman 却没有?
为啥我的 JavaScript 代码会收到“请求的资源上不存在 'Access-Control-Allow-Origin' 标头”错误,而 Postman 却没有?