GWT HTTP request response code 0 with CORS working

2019-04-02 03:52发布

问题:

I am using GWT 2.4 to build an application that runs entirely client-side and uses a web service that I control but is hosted on a different server. On this Java Servlet web service, I have implemented doOptions like so:

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

And client-side in GWT I submit a request the standard way, e.g.

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();
    }
}

And then my callback implements onResponseReceived like this:

@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());
    }
}

Whenever I run the application in late versions of Chrome or Firefox and send a request, onResponseReceived is called but the response code is 0 and there is no error message. Research indicates that most other instances of this problem arise from SOP restrictions. However, when looking at the HTTP traffic in Fiddler I see that when this is executed, the browser is indeed sending the expected HTTP request, and the web service is indeed returning the expected response, with a 200 response code. Somehow, the browser just isn't handling it properly.

Update: when I look at the traffic in Fiddler, it indicates that the request is sent and a response is received, but when I look at the same request in Chrome's developer console it shows that the request is 'canceled'. If the request is actually happening, what does that mean in this context?

Has anyone run across this problem? Any suggestions on what may be going on?

回答1:

Error code 0 means that the CORS has been aborted, check that your servlet implementation is all right, I think you have to send Allow instead of Access-Control-Allow-Methods, and also you have to add the Access-Control-Allow-Headers since GWT adds extra headers to ajax requests.

Try this implementation from the gwt-query example which works fine:

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");
  }
}

I would rather a filter instead a servlet, like in the link above is explained, though.