使用 python flask-restful 和消费 AngularJS(使用 $http)时出现 CORS(跨源...)错误
Posted
技术标签:
【中文标题】使用 python flask-restful 和消费 AngularJS(使用 $http)时出现 CORS(跨源...)错误【英文标题】:Getting CORS (Cross-Origin...) error when using python flask-restful with consuming AngularJS (using $http) 【发布时间】:2014-07-07 15:02:34 【问题描述】:我使用 python 程序提供带有 Flask-restful 扩展的 RESTful 服务。 我想用 AngularJS 应用程序来使用它。我的本地主机上一切正常(目前)。 为了使用服务,我使用 AngularJS $http,如下所示。 每次我打电话时,我都会收到这个该死的 CORS 错误(见下文)......
在搜索了一天半之后,我尝试了很多不同的东西,但没有任何东西可以帮助我防止这个问题,我真的不知道还能做什么。不幸的是,flask-restful 网站上没有官方文档。
我不确定我是否遗漏了任何明显的东西,或者这是否真的很难在这种技术组合中工作......
在我的帖子末尾,您会看到我已经尝试过的事情的列表...
顺便说一句,一个简单的curl
工作......
我很乐意提供任何帮助!
这里是相关的python代码:
app = Flask(__name__)
api = Api(app)
class DatabaseRestRoomList(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument('name', type=str, required=True,
help='No room name provided')
super(DatabaseRestRoomList, self).__init__()
def get(self):
#make some logic to give a dict for the variable roomlist
return (roomlist)
def post(self):
args = self.reqparse.parse_args()
name = args['name']
db.createRoom(name)
return ('success': 'yes')
api.add_resource(DatabaseRestRoomList, '/room')
if __name__ == '__main__':
app.run(debug=True)
这是我的 Angularjs 服务代码:
app.service('deviceService', ['$http',
function ($http)
this.getAllRooms = function ()
var roomlist;
var urlbase = "http://localhsot:5000"
var urltail = "room"
var newroom = 'name': "NewXYRoom" ;
$http.post(urlbase + '/' + urltail, newroom).
success(function (data, status, headers, config)
alert("success");
).
error(function (data, status, headers, config)
alert("error..")
);
]);
当我尝试执行 get 或 post 两次时,我得到了这个 cors 错误...(当然还有我的错误警报)
XMLHttpRequest cannot load http://localhsot:5000/room. No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin 'http://localhost:53144' is therefore not allowed access.
如果我“仅”执行GET
,则错误会发生在 get 本身上。如果我执行POST
,我会在OPTIONS
得到错误。
这些是帖子的标题(从萤火虫网络选项卡复制)
Answer-Header
Cache-Control no-cache
Connection Keep-Alive
Content-Length 619
Content-Type text/html; charset=utf-8
Pragma no-cache
Proxy-Connection Keep-Alive
Request-Header
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,de-de;q=0.8,de;q=0.5,en;q=0.3
Access-Control-Request-He... content-type
Access-Control-Request-Me... POST
Cache-Control no-cache
Connection keep-alive
Host localhsot:5000
Origin http://localhost:53144
Pragma no-cache
User-Agent Mozilla/5.0 (Windows NT 6.3; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
我已经试过了
在 get 和 post 方法上方添加@cors.crossdomain(origin='*')
(https://github.com/twilio/flask-restful/pull/131)
将此api.decorators=[cors.crossdomain(origin='*')]
添加到整个api (TypeError on CORS for flask-restful)
如您所见,我已经点击了此处提供的答案之一 (Flask RESTful cross-domain issue with Angular: PUT, OPTIONS methods) 中的链接,但我没有得到实际答案。我不想重写任何后端,options 方法对我的课程也没有帮助......
【问题讨论】:
可能是端口号的原因。您可以在 CORS 策略中包含端口号吗? (作为域的一部分) “不幸的是,flask-restful 站点上没有官方文档”这不是 flask-restful 的错误。这是http服务器。正如Halcyon所说,它很可能是端口号。你在生产中使用什么?烧瓶http服务器?独角兽?如果我是你,我会尽量避免 CROS。您必须选择:1 服务来自同一个域 2. 使用 Jsonp 好吧,现在我在 Flask 服务器上运行 flask-restful 服务和我的 Angularjs 站点。然后它当然可以工作,因为它在同一个网络服务器上。 (在我用这个开发之前,我在我的visualstudio上运行了angularjs)它不能解决问题,我在问题中描述的星座无法正确处理这个cors请求。但它不再影响我了。 【参考方案1】:您可以使用 after_request 挂钩解决此问题:
@app.after_request def after_request(响应): 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') 返回响应您可以在此处查看有关如何使用它的演示 - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-1/
本教程还使用了 Flask-restful。
【讨论】:
【参考方案2】:如果您使用 CORS 进行 AngularJS POST
调用,有时它会触发(取决于您的 MIME/Content-Type)先前的 OPTIONS
调用,以在发送所有 POST
之前检查跨服务器请求是否有效数据。由于您的 API 没有 options
方法,因此 Flask 接受调用而不是 Flask-Restful,并且它不会设置仅为 API 资源定义的 CORS 选项。
你可以解决定义一个虚拟options
处理程序的问题:
def options(self):
pass
要使整个事情正常工作,请使用定义 cors 选项
api.decorators = [cors.crossdomain(origin='*', headers=['accept', 'Content-Type'])]
我不知道为什么,但我必须明确地将所有headers
添加到列表中;使用headers = '*'
对我不起作用。在将资源连接到 API 之前,您可能还必须添加装饰器。
【讨论】:
【参考方案3】:正如on another thread 所发布的,这是我的解决方案:
要在您的 Web 服务 api 上允许远程 CORS 请求,您可以像这样简单地初始化您的烧瓶 restful API:
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
from flask_cors import CORS
app = Flask(__name__)
cors = CORS(app, resources=r"*": "origins": "*")
api = Api(app)
这会将 CORS 标头添加到您的 api 实例中,并允许对来自每个来源的每个路径的 CORS 请求。
【讨论】:
【参考方案4】:Flask 扩展 Flask-cors (https://github.com/corydolphin/flask-cors) 对我来说效果很好。
【讨论】:
以上是关于使用 python flask-restful 和消费 AngularJS(使用 $http)时出现 CORS(跨源...)错误的主要内容,如果未能解决你的问题,请参考以下文章
Python Flask-Restful POST不接受JSON参数