简体   繁体   English

在CORS上的TypeError为烧瓶休息

[英]TypeError on CORS for flask-restful

While trying the new CORS feature on flask-restful, I found out that the decorator can be only applied if the function returns a string. 在burn-restful上尝试新的CORS功能时,我发现只有在函数返回一个字符串时才能应用装饰器。

For example, modifying the Quickstart example : 例如,修改Quickstart示例

class HelloWorld(restful.Resource):
    @cors.crossdomain(origin='*')
    def get(self):
        return {'hello': 'world'}

Throws: 抛出:

TypeError: 'dict' object is not callable

Am I doing something wrong? 难道我做错了什么?

I recently came across this issue myself. 我最近自己遇到过这个问题。 @MartijnPieters is correct, decorators can't be called on single methods of the view. @MartijnPieters是正确的, decorators不能在视图的单个方法上调用。

I created an abstract base class that contained the decorator list. 我创建了一个包含 decorator列表的抽象基类。 The class that consumes Resource (from flask-restful) also inherits the base class, which is the class actually applying the decorator list to the view. 使用 Resource的类(来自flask-restful)也继承了基类,这是实际将装饰器列表应用于视图的类。

 
 
 
  
   class AbstractAPI(): decorators = [cors.crossdomain(origin='*')] class HelloWorld(restful.Resource, AbstractAPI): #content
 
  

nope. 不。

just add the decorator list to the parameters after you create the Api instance 在创建Api实例后,只需将装饰器列表添加到参数中

api = Api(app)
api.decorators=[cors.crossdomain(origin='*')]

The return value of the wrapped function is passed (as one argument) to flask.make_response() ; 包装函数的返回值作为一个参数传递给flask.make_response() ; anything that a normal Flask view can return is acceptable. 普通 Flask视图可以返回的任何内容都是可以接受的。 The decorator is essentially the same as this Flask snippet . 装饰器与此Flask片段基本相同。

Because the Flask-restful Resource is a subclass of flask.views.MethodView you should really not put decorators directly on the methods here. 因为Flask-restful Resourceflask.views.MethodView的子类, flask.views.MethodView你真的应该把装饰器直接放在这里的方法上。 As documented in Decorating Views you should list view decorators in a special class attribute, decorators which is a list: 装饰视图中所述,您应该在特殊的类属性中列出视图装饰器, decorators是一个列表:

class HelloWorld(restful.Resource):
    decorators = [cors.crossdomain(origin='*')]

    def get(self):
        return {'hello': 'world'}

and Flask will apply the view to the actual view method returned by HelloWorld.as_view() , which is what Flask actually calls when dispatching the route to the view. 并且Flask会将视图应用于HelloWorld.as_view()返回的实际视图方法,这是Flask在将路径分派给视图时实际调用的方法。

Applying them directly to the methods will only server to confuse the restful.Resource dispatcher as it is expecting methods to return python datastructures suitable for encoding to JSON, which is not what cors.crossdomain() returns anyway. 将它们直接应用于方法只会服务器混淆restful.Resource调度程序,因为它期望方法将适合编码的python数据结构返回到JSON,这不是cors.crossdomain()无论如何返回的。

I found that you can still use the decorator provided you return a string or JSON response (which is probably good practice for an API anyway). 我发现你仍然可以使用装饰器,只要你返回一个字符串或JSON响应(这无论如何都可能是API的好习惯)。 This is important if you want to do route-specific CORS headers, using the decorator makes life much easier. 如果你想做特定于路由的CORS头文件,这很重要,使用装饰器可以让生活变得更轻松。 See this merged pull req for more information: https://github.com/flask-restful/flask-restful/pull/131 有关更多信息,请参阅此合并的pull req: https//github.com/flask-restful/flask-restful/pull/131

Here's an example: 这是一个例子:

from . import app
from flask_restful import reqparse, abort, Api, Resource
from flask.ext.cors import cross_origin
from datetime import datetime
from flask import jsonify

api = Api(app)


class DateTime(Resource):
    @cross_origin(origins="http://localhost:63342*")
    def get(self):
        return jsonify({'DateTime': str(datetime.today())})

api_root = '/api/v1/'
api.add_resource(DateTime, api_root + 'DateTime')

If you're using flask-security, adding auth decorators had some weird behavior in my testing. 如果您正在使用flask-security,添加auth修饰符在我的测试中有一些奇怪的行为。 I recommend assert current_user.is_authenticated instead. 我推荐使用assert current_user.is_authenticated If you are allowing credentials, make sure to CSRF protect. 如果您允许凭据,请确保CSRF保护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM