Flask-RESTplus CORS请求不在响应中添加标头

时间:2018-06-05 20:57:55

标签: python rest flask

我在尝试为REST API设置CORS时遇到问题。 我目前正在使用Flask-Restplus包。这是我的端点的样子:

@api_ns.route('/some/endpoint')
@api_ns.response(code=400, description='Bad Request.')
class AEndpointResource(Resource):

    @api_ns.param(**api_req_fields.POST_DOC)
    @api_ns.expect(POST_REQUIRED_BODY)
    @api_ns.marshal_with(code=201,
                     fields=my_api_models.MyEndpointResponse.get_serializer(),
                     description=my_api_models.MyEndpointResponse.description)
    def post(self) -> Tuple[my_api_models.MyEndpointResponse, int]:
        """
        The post body
        """
        # Some logic here
        return response, 200

如果我编写一个小的javascript代码段并尝试在浏览器中启动它,我会收到错误,因为没有CORS标头。我看到Flask-Restplus已经处理了OPTIONS请求而没有告诉他任何事情。 (根据this link这是有道理的,提到自Flask 0.6以来,OPTIONS请求会自动处理)

我的问题是即使我尝试使用以下方法装饰我的端点:

from flask-restplus import cors   # <--- Adding this import

...
class AnEndpointResource(Resource):
    ...
    @my_other_decorators
    ...
    @cors.crossdomain(origin='*')  # <--- Adding this new decorator on my endpoint
    def post(self) -> Tuple[my_api_models.MyEndpointResponse, int]:
        ...

没有任何变化,我仍然得到与以前相同的结果。我像以前一样自动处理OPTIONS请求中的HTTP 200,但是我没有在响应中看到我的新标题(即Access-Control-Allow-Origin)。

我错过了什么吗?

5 个答案:

答案 0 :(得分:1)

我也遇到了CORS问题,并解决了问题this way

from flask import Flask
from flask_restplus import Api

app = Flask('name')
api = Api(app)

// your api code here


@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*')

答案 1 :(得分:1)

在笔记本电脑和浏览器上进行本地测试时,我可以通过在响应中添加标题来解决cors问题。

之前:return state, 200

之后:return state, 200, {'Access-Control-Allow-Origin': '*'}

答案 2 :(得分:1)

使用Flask-CORS,它可以正常工作:

from flask import Flask, request
from flask_restplus import Resource, Api, fields
from flask_cors import CORS

# configuration
DEBUG = True

# instantiate the app
app = Flask(__name__)
api = Api(app)
app.config.from_object(__name__)

# enable CORS
CORS(app, resources={r'/*': {'origins': '*'}})

答案 3 :(得分:0)

我测试过,您要查找的标头会添加到对后续GET请求的响应中。装饰器@cors.crossdomain有一个选项automatic_options,默认情况下设置为True。这意味着您的OPTIONS请求仍将自动处理。

请参阅this测试,了解它应如何运作。

flask_restplus.cors模块未记录,因此不确定是否应该使用它。

答案 4 :(得分:0)

问题是flask-restplus仅将CORS标头分配给GET请求。当浏览器发出OPTIONS请求时,Resource类上的方法不会处理此方法。然后,您会看到一个闪烁的CORS标头:一个请求有效,下一个无效,等等

引发404时,也会跳过CORS装饰器。

解决这些错误的方法是使用类似的方法:

def exception_to_response(func):
    @wraps(func)
    def _exc_to_resp_decorator(self, *args, **kwargs):
        try:
            return func(self, *args, **kwargs)
        except Exception as e:
            return self.api.handle_error(e)

    return _exc_to_resp_decorator


@api.route("/your-endpoint")
class SomeEndpoint(Resource):
    @cors.crossdomain(origin='*')
    def options(self):
        # Make sure the OPTIONS request is also handled for CORS
        # The "automatic_options" will handle this, no need to define a return here:
        return

    @api.expect(my_schema)
    @api.response(200, "Success")
    @cors.crossdomain(origin='*')
    @exception_to_response
    def get(self):
        return {"json-fields": 123}, 200