【问题标题】:Flask-RESTplus CORS request not adding headers into the responseFlask-RESTplus CORS 请求未将标头添加到响应中
【发布时间】:2018-11-15 10:56:35
【问题描述】:

我在尝试为我的 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 sn-p 代码并尝试在浏览器中启动它,我会收到错误消息,因为没有 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)。

我错过了什么吗?

【问题讨论】:

    标签: python rest flask


    【解决方案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': '*'}})
    

    【讨论】:

      【解决方案2】:

      问题在于 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
      

      【讨论】:

        【解决方案3】:

        我也遇到了 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', '*')
            return response
        

        【讨论】:

        【解决方案4】:

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

        之前:return state, 200

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

        【讨论】:

        • 谢谢@user985366。这是我发现为使用 response marshallingflask_restplus 路由启用 CORS 的唯一方法@
        【解决方案5】:

        我进行了测试,您正在寻找的标头已添加到后续GET 请求的响应中。装饰器@cors.crossdomain 有一个选项automatic_options,默认设置为True。这意味着您的 OPTIONS 请求仍将被自动处理。

        请参阅this 测试以检查它应该如何工作。

        flask_restplus.cors 模块没有记录,所以不确定是否应该使用它。

        【讨论】:

          猜你喜欢
          • 2016-03-24
          • 2016-05-15
          • 2019-09-05
          • 2020-11-05
          • 1970-01-01
          • 2016-09-28
          • 2019-05-05
          • 2015-11-13
          • 2020-03-16
          相关资源
          最近更新 更多