webapp2和Access-Control-Allow-Origin

时间:2014-02-22 17:39:13

标签: javascript python ajax webapp2

我在谷歌应用引擎应用中使用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请求吗?

2 个答案:

答案 0 :(得分:2)

今天正在讨论这个问题以及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()

答案 1 :(得分:0)

为什么将all路由到单个方法:simple_login。为什么不在处理程序中使用def选项(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

但现在我们有了云端点。