2

私は GWT 2.4 を使用して、完全にクライアント側で実行され、私が制御しているが別のサーバーでホストされている Web サービスを使用するアプリケーションを構築しています。この Java サーブレット 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 の開発者コンソールで同じリクエストを見ると、リクエストが「キャンセル」されていることがわかります。リクエストが実際に発生している場合、このコンテキストではどういう意味ですか?

誰かがこの問題に遭遇しましたか? 何が起こっているのかについての提案はありますか?

4

1 に答える 1

1

Allowエラー コード 0 は、CORS が中止されたことAccess-Control-Allow-Methodsを意味します。サーブレットの実装が適切であることを確認してくださいAccess-Control-Allow-Headers

正常に動作するgwt-query の例からこの実装を試してください。

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

ただし、上記のリンクで説明されているように、サーブレットの代わりにフィルターを使用したいと思います。

于 2013-04-03T17:59:26.533 に答える