【问题标题】:webapp2 and the Access-Control-Allow-Originwebapp2 和 Access-Control-Allow-Origin
【发布时间】:2014-03-24 08:27:01
【问题描述】:

我在谷歌应用引擎应用中使用 webapp2。基本上我已经构建了一个 REST API,我试图从一个 javascript ajax 客户端连接到它。我面临的问题是如何正确实现 Access-Control-Allow-Origin 标头。我有一个可行的解决方案,但对我来说看起来很笨拙。任何人都可以提出更好的方法吗?

这是我目前的解决方案:

在我的主路由文件中:

webapp2.Route(r'/<v>/logins/simple',
                      handler=controllers.login_c.LoginController,
                      name='simple_login', handler_method='simple_login',
                      methods=['GET', 'POST', 'OPTIONS']),

然后在控制器中:

class LoginController(webapp2.RequestHandler):
def simple_login(self, v):
    self.response.headers.add_header('Access-Control-Allow-Origin', '*')
    self.response.headers.add_header('Access-Control-Allow-Headers',
                                     'Origin, X-Requested-With, Content-Type, Accept')
    self.response.headers.add_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE')
    self.response.headers.add_header('Content-Type', 'application/json')
    if not self.request.__str__().startswith("OPTIONS"):
        ...more code

但是这个解决方案意味着我必须在每个控制器中复制标题。我不能有东西来捕获所有的 OPTIONS 请求吗?

【问题讨论】:

    标签: javascript python ajax webapp2


    【解决方案1】:

    今天正在讨论这个问题,OP 的问题:

    我不能有东西来捕获所有的 OPTIONS 请求吗?

    ...我也有。我创建了一个包装类,我的 restful 端点类可以继承它,它包括一个默认的OPTIONS 处理程序。这也可以在dispatch 方法中完成,如this SO post 所示。

    main.py

    import webapp2
    
    from controllers import widgets_controller
    
    APP = webapp2.WSGIApplication([
        ('/rest/widgets/all', widget_controller.All),
        ('/rest/widgets/create', widget_controller.Create),
    ], debug=True)
    

    widgets_controller.py

    class Create(rest.RestHandler):
    
        def post(self):
            # We use this for any POST, PUT, and DELETE, where necessary.
            self.decorateHeaders();
    
            # Handle the rest of the request here...
    

    rest_controller.py

    class RestHandler(webapp2.RequestHandler):
        def decorateHeaders(self):
            """Decorates headers for the current request."""
            self.response.headers.add_header('Access-Control-Allow-Origin', '*')
            self.response.headers.add_header('Access-Control-Allow-Headers', 'Authorization')
            self.response.headers.add_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE')
    
        def options(self):
            """Default OPTIONS handler for the entire app."""
            self.decorateHeaders()
    

    【讨论】:

      【解决方案2】:

      为什么要全部路由到一个方法:simple_login。为什么不在处理程序中使用 def options(self)?

      我使用类似的东西:

      class RPCHandler(webapp.RequestHandler):
      
          def options(self):
              self.response.headers['Access-Control-Allow-Origin'] = '*'
              self.response.headers['Access-Control-Allow-Headers'] = '*'
              self.response.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
      
          def post(self):
      
              self.response.headers['Access-Control-Allow-Origin'] = '*'
              self.response.headers['Access-Control-Allow-Headers'] = '*'
              self.response.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
              .... more code to handle the rpc ....
      
      def main():
          app = webapp.WSGIApplication([
              ('/', MainPage),
              ('/rpchr', RPCHandler),
              ], debug=True)
          util.run_wsgi_app(app)
      
      if __name__ == '__main__':
          main()
      

      示例取自一些用于处理 json 请求的旧 webapp Python 2.5 应用程序。但它现在可以正常工作几年了。

      来自 app.yaml:

      - url: /rpchr                     
        script: main.py
        secure: always
      
      - url: /                          
        script: main.py
        secure: always
        login: admin
      

      但现在我们有了云端点。

      【讨论】:

        猜你喜欢
        • 2016-09-30
        • 2013-10-28
        • 2017-06-15
        • 2015-06-17
        • 2013-01-20
        • 2014-01-12
        • 2017-12-29
        • 2019-02-07
        • 2019-03-12
        相关资源
        最近更新 更多