Google App Engine 和 CORS

2022-09-04 20:58:37

我有一个简单的应用程序(java servlet)托管在GAE上。应用返回 json 数据。我已经在servlet中设置了标头信息,如下所示:

resp.setContentType("application/json");
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
resp.setHeader("Access-Control-Allow-Credentials", "true");

以下是我直接在应用引擎上转到 URL 时的标题信息:

Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:---------.appspot.com
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko)         Chrome/18.0.1025.162 Safari/535.19
Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*
Cache-Control:private
Content-Encoding:gzip
Content-Length:340
Content-Type:application/json; charset=ISO-8859-1
Date:Sat, 28 Apr 2012 19:14:58 GMT
Server:Google Frontend
Vary:Accept-Encoding

但是当我尝试从其他域访问URL时,我得到以下响应:

Request Method:OPTIONS
Status Code:500 Internal Server Error
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, x-requested-with, accept
Access-Control-Request-Method:GET
Connection:keep-alive
Host:----------.appspot.com
Origin:http://--------------.com
Referer:http://-------------.com/map/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.162 Safari/535.19
Response Headersview source
Content-Length:466
Content-Type:text/html; charset=UTF-8
Date:Sat, 28 Apr 2012 19:15:14 GMT
Server:Google Frontend

这是确切的错误:

XMLHttpRequest cannot load http://----------.appspot.com/Locations. Origin http://-------------.com is not allowed by Access-Control-Allow-Origin.

尝试访问 GAE URL 的代码如下所示:

$.getJSON("http://---------appspot.com/Locations",function(result){
    for (i=0; i < result.length; i++)

任何帮助将不胜感激。


答案 1

您需要覆盖标准的 HttpServlet.doOptions() 方法以支持正确的预检请求处理

@Override
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
{ 
    // pre-flight request processing
    resp.setHeader("Access-Control-Allow-Origin", "*");
    resp.setHeader("Access-Control-Allow-Methods", SUPPORTED_METHODS);
    resp.setHeader("Access-Control-Allow-Headers", SUPPORTED_HEADERS);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
{
   resp.setHeader("Access-Control-Allow-Origin", "*");
   resp.setContentType("application/json");

   // implementation...
}

可以在此处找到一篇解释CORS和示例的精彩文章。


答案 2

预检请求中,您的请求似乎在早期失败,因为在请求时,服务器响应了 500 个(它应该以 200 多个特定标头响应)。OPTIONS <URL>

你可能想要查看有关 CORS 的 HTML5rocks 教程,特别是向服务器添加 CORS 支持,其中解释了预检请求(请求,你的应用无法使用 200 多个必需标头进行回复)。OPTIONS <url>


推荐