CORS – 使用AJAX在Python(webapp2)Web服务上发布
这将是漫长的:
好的,我正在开发一个谷歌日历小工具,它将请求发送到托管在Google App Engine上的Python webapp2 REST api。
当我尝试发布因CORS而不允许我发布的内容时,问题就来了。 在Chromes的DevTools中它说:
Method: OPTIONS. Status: (failed) Request header field Content-Type is not allowed by Access-Control-Allow-Headers. Origin https://hq34i4geprnp5vci191ljfuhcoerscl4-a-calendar-opensocial.googleusercontent.com is not allowed by Access-Control-Allow-Origin.
我知道这是因为CORS。 这里:
Ajax – Access-Control-Allow-Origin不允许使用Origin localhost
它说我必须添加
Access-Control-Allow-Origin: *
对于标题,但是我又是ajax的新手,我想知道它是否以这种方式完成:
$.ajax({ type: "POST", url: "https://myapp.appspot.com/service", contentType: "application/json; charset=utf-8", data: data, beforeSend: function (request) { request.setRequestHeader("Access-Control-Allow-Origin", "*"); } success: function(data) { alert("AJAX done"); } });
添加此标题的输出是不同的 (这让我想知道原点是否被允许,但我真的不知道):
Method: OPTIONS. Status: (failed) Request header field Content-Type is not allowed by Access-Control-Allow-Headers. XMLHttpRequest cannot load https://myapp.appspot.com/service. Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers.
我甚至发现了这个:
http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
这让我可以做GET请求,但是我想学习如何在没有这个的情况下完成它们。
同样在我的网络服务器上,我有这个:
... class webService(webapp2.RequestHandler): options(self): self.response.write('options') post(self): self.response.write('post') application = webapp2.WSGIApplication([ ('/', MainPage), ('/service', webService) ], debug=True)
我不知道是否必须向网络服务器添加更多内容,我也没有找到信息说我必须这样做。 此外,我认为我即将实现CORS请求,但是,我找不到解释这一切的示例。
请帮忙。
好的,我修好了。
首先,我在这里意识到标头是由服务器发送的,所以我在AJAX请求中发送这些标头时做错了。
最后,在搜索了全球网络后,我发现了我所缺少的内容。 这是愚蠢的事情。 我找到了修复它的页面:
http://enable-cors.org/server_appengine.html
所以最后一切看起来像这样:
$.ajax({ type: "POST", url: "https://myapp.appspot.com/service", contentType: "application/json; charset=utf-8", data: data, success: function(data) { alert("AJAX done"); } });
并在webService中:
class webService(webapp2.RequestHandler): def get(self): self.response.headers.add_header('Access-Control-Allow-Origin', '*') self.response.headers['Content-Type'] = 'application/json' # do something def post(self): self.response.headers.add_header('Access-Control-Allow-Origin', '*') self.response.headers['Content-Type'] = 'application/json' # do something def options(self): self.response.headers['Access-Control-Allow-Origin'] = '*' self.response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept' self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE'
我只是想指出一个可能对其他人有帮助的细节:
浏览器在处理“Access-Control-Allow-Orgin”标头方面有所不同。 例如,我发现当标头值为通配符(*)时Chrome会阻止跨域post,如上面的解决方案代码中所示。 它认为它过于自由,想要一个特定的起源。 然而,其他浏览器,如IE和FireFox并不关心。
因此,如果要构建跨浏览器解决方案,最好将“Access-Control-Allow-Origin”的值设置为随请求一起发送的Origin值。
如果您正在使用SSL,那么您将遇到一些其他需要测试的差异。
如果你需要一个轻量级的解决方案,这可以用POJS(普通的JavaScript)完成,而不需要使用jQuery。 只需连接IE8 +的window.XDomainRequest和其他浏览器的window.XMLHttpRequest即可开展业务。
用调度方法可以更简单
class BaseRequestHandler(webapp2.RequestHandler): def dispatch(self): self.response.headers.add_header('Access-Control-Allow-Origin', '*') self.response.headers.add_header('Access-Control-Allow-Headers', 'Content-Type') webapp2.RequestHandler.dispatch(self) class LoginHandler(BaseRequestHandler): def login(self): #code here
- CORS + Cordova:问题:Access-Control-Allow-Origin
- HTTP标头设置授权标头停止加载数据
- 跨源Ajax请求在Opera和IE9中不起作用?
- 在WCF服务上启用CORS。 获取HTTP 405:不允许的方法
- 如何从javascript调用IBM Watson服务
- 使用Javascript进行基本授权API登录(CORS?)
- Java Spring REST API CORS不适用于通过jQuery与Chrome进行DELETE请求
- 如何修复没有’Access-Control-Allow-Origin’标题出现’错误
- 允许cors jQuery POST请求Express.js服务器上的Spotify API