GWT HTTP 请求响应代码 0 与 CORS 工作

Posted

技术标签:

【中文标题】GWT HTTP 请求响应代码 0 与 CORS 工作【英文标题】:GWT HTTP request response code 0 with CORS working 【发布时间】:2013-03-25 10:23:24 【问题描述】:

我正在使用 GWT 2.4 构建一个完全在客户端运行并使用我控制但托管在不同服务器上的 Web 服务的应用程序。在这个 Java Servlet Web 服务上,我已经实现了 doOptions,如下所示:

protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    response.addHeader("Access-Control-Allow-Origin", "*");
    response.addHeader("Access-Control-Allow-Methods", "POST, GET");

我在 GWT 中的客户端以标准方式提交请求,例如

public static void makeHttpGetRequest(String query, RequestCallback callback) 
    String url = "http://example.webservice.com/endpoint" + "?q=" + query;

    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
    try 
        builder.sendRequest(query, callback);
     catch (RequestException e) 
        Window.alert("Server encountered an error: \n" + e.getMessage());
        e.printStackTrace();
    

然后我的回调像这样实现 onResponseReceived:

@Override
public void onResponseReceived(Request request, Response response) 
    if (response.getStatusCode() == 200) 
        System.out.println("HTTP request successful, received "
                + response.getText());
        processResponse(response.getText());
     else 
        System.out.println("HTTP error code " + 
                response.getStatusCode() + ":" + 
                response.getStatusText());
    

每当我在 Chrome 或 Firefox 的最新版本中运行应用程序并发送请求时,都会调用 onResponseReceived 但响应代码为 0 并且没有错误消息。研究表明,这个问题的大多数其他实例都是由 SOP 限制引起的。但是,当查看 Fiddler 中的 HTTP 流量时,我看到执行此操作时,浏览器确实发送了预期的 HTTP 请求,并且 Web 服务确实返回了预期的响应,响应代码为 200。不知何故,浏览器只是没有正确处理它。

更新:当我查看 Fiddler 中的流量时,它表明请求已发送并收到响应,但是当我在 Chrome 的开发者控制台中查看相同的请求时,它显示该请求已“取消”。如果请求确实发生了,那么在这种情况下这意味着什么?

有人遇到过这个问题吗?对可能发生的事情有什么建议吗?

【问题讨论】:

【参考方案1】:

错误代码 0 表示 CORS 已中止,请检查您的 servlet 实现是否正常,我认为您必须发送 Allow 而不是 Access-Control-Allow-Methods,而且您必须添加 Access-Control-Allow-Headers,因为 GWT向 ajax 请求添加额外的标头。

从gwt-query example 尝试这个实现,效果很好:

private static final String ALLOWED_DOMAINS_REGEXP = ".*";

HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;

String origin = req.getHeader("Origin");
if (origin != null && origin.matches(ALLOWED_DOMAINS_REGEXP)) 
  resp.addHeader("Access-Control-Allow-Origin", origin);
  resp.setHeader("Allow", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
  if (origin != null) 
      String headers = req.getHeader("Access-Control-Request-Headers");
      String method = req.getHeader("Access-Control-Request-Method");
      resp.addHeader("Access-Control-Allow-Methods", method);
      resp.addHeader("Access-Control-Allow-Headers", headers);
      resp.setContentType("text/plain");
  

不过,我宁愿使用过滤器而不是 servlet,就像上面的链接中解释的那样。

【讨论】:

谢谢!这行得通。我所做的与此过滤器效果之间的具体区别在于,之前,我只从 OPTIONS 请求中返回“访问控制源”标头,而此标头也需要添加到 GET 请求中。 @Manolo req.getHeader("Origin") 在我的情况下返回空值。请帮忙。 Origin 标头仅针对支持 CORS 的浏览器发送,IE9 不起作用,这是您的情况吗?

以上是关于GWT HTTP 请求响应代码 0 与 CORS 工作的主要内容,如果未能解决你的问题,请参考以下文章

http://localhost:4200' 已被 CORS 策略阻止:对预检请求的响应未通过

对 CORS 预检的响应具有 HTTP 状态代码 405

CORS 问题:预检响应具有无效的 HTTP 状态代码 403

GWT-RPC:对请求有效负载的黑客攻击

CORS 问题? - 预检响应包含无效的 HTTP 状态代码 405

CORS 预检响应错误