【问题标题】:POST GWT CORS request works but PUT CORS request doesn'tPOST GWT CORS 请求有效,但 PUT CORS 请求无效
【发布时间】:2023-03-14 03:43:01
【问题描述】:

我正在为个人项目编写 GWT 前端,但遇到一些 HTTP 请求问题。当我发出 CORS POST 请求时,它工作正常

String url = BASE_URL + "students/";

RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
builder.setHeader("Content-Type", "application/vnd.onelostlogician.student+json");
builder.setHeader("Accept", "application/json");
StringBuilder basicAuth = new StringBuilder();
basicAuth.append(username.getValue());
basicAuth.append(":");
basicAuth.append(password.getValue());
String basicAuthStr = basicAuth.toString();
builder.setHeader("Lambda-Authorization", "Basic " + toBase64(basicAuthStr.getBytes()));
StudentWriter studentWriter = GWT.create(StudentWriter.class);

try {
    builder.sendRequest(studentWriter.write(student), new RequestCallback() {
        public void onError(Request request, Throwable exception) {
            addItemDialog.close();
            responseDialog.open();
            loadingIcon.setVisible(false);
            responseHeading.setText("No response");
            responseLabel.setText(request.toString());
        }

        public void onResponseReceived(Request request, Response response) {
            loadingIcon.setVisible(false);
            String responseText = response.getText();

            List<Map.Entry<Integer, Student>> students = model.getList();
            Integer studentId = Integer.parseInt(responseText);

            students.add(new AbstractMap.SimpleEntry<>(studentId, student));
            model.setList(students);

            // clear text fields
            className.setValue("");
            additionLevel.setValue("");
            additionProblems.setValue("");
            subtractionLevel.setValue("");
            subtractionProblems.setValue("");
            multiplicationLevel.setValue("");
            multiplicationProblems.setValue("");
            divisionLevel.setValue("");
            divisionProblems.setValue("");

            addItemDialog.close();
        }
    });

} catch (RequestException _) {
    // Code omitted for clarity
}

options 请求得到 200 响应(下面的 chrome 网络检查):

General
Request URL:https://[redacted].execute-api.eu-west-1.amazonaws.com/v1/students/
Request Method:OPTIONS
Status Code:200 
Remote Address:54.230.9.41:443
Referrer Policy:no-referrer-when-downgrade

Response Headers
access-control-allow-headers:content-type, lambda-authorization
access-control-allow-methods:post, get, put
access-control-allow-origin:*
content-length:0
content-type:application/json
date:Wed, 13 Sep 2017 14:56:32 GMT
status:200
via:1.1 5db82aafd9021b07695423274288b59e.cloudfront.net (CloudFront)
x-amz-cf-id:8nJ2gzqHFPiiDOOeEelzkpI7Ga9SFdEcljiLt2pvm7Z995_GicxPVw==
x-amzn-requestid:bb0e23db-9893-11e7-bbbe-9bea7d9d70bf
x-amzn-trace-id:sampled=0;root=1-59b94720-d892209d8c5c2a04832bdb85
x-cache:Miss from cloudfront

Request Headers
:authority:[redacted].execute-api.eu-west-1.amazonaws.com
:method:OPTIONS
:path:/v1/students/
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:en-GB,en-US;q=0.8,en;q=0.6
access-control-request-headers:content-type,lambda-authorization
access-control-request-method:POST
origin:http://127.0.0.1:8888
referer:http://127.0.0.1:8888/ArithmeticExerciseGeneratorClient.html
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

然后POST请求按预期发生

General
Request URL:https://[redacted].execute-api.eu-west-1.amazonaws.com/v1/students/
Request Method:POST
Status Code:201 
Remote Address:54.230.9.41:443
Referrer Policy:no-referrer-when-downgrade

Response Headers
access-control-allow-origin:*
content-length:1
content-type:application/json
date:Wed, 13 Sep 2017 14:56:33 GMT
status:201
via:1.1 5db82aafd9021b07695423274288b59e.cloudfront.net (CloudFront)
x-amz-cf-id:gxYrwctM75ObiPyS4nD69jXSO4dBaMAOZmXXX0mPE4wMgCdcjUSQsA==
x-amzn-requestid:bb381a33-9893-11e7-a1f1-17fd67ca388c
x-amzn-trace-id:sampled=0;root=1-59b94720-1c1e3a8d8c9ce2741c789241
x-cache:Miss from cloudfront

Request Headers
:authority:[redacted].execute-api.eu-west-1.amazonaws.com
:method:POST
:path:/v1/students/
:scheme:https
accept:application/json
accept-encoding:gzip, deflate, br
accept-language:en-GB,en-US;q=0.8,en;q=0.6
content-length:224
content-type:application/vnd.onelostlogician.student+json
lambda-authorization:Basic [redacted]
origin:http://127.0.0.1:8888
referer:http://127.0.0.1:8888/ArithmeticExerciseGeneratorClient.html
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

Request Payload
{"className":"6T","additionProblemId":4,"additionNoOfProblems":5,"subtractionProblemId":3,"subtractionNoOfProblems":5,"multiplicationProblemId":2,"multiplicationNoOfProblems":5,"divisionProblemId":1,"divisionNoOfProblems":5}

不幸的是,对同一服务器上非常相似的资源的 PUT 请求不会。代码几乎相同:

String url = BASE_URL + "students/" + studentId;

RequestBuilder builder = new RequestBuilder(RequestBuilder.PUT, url);
builder.setHeader("Content-Type", "application/vnd.onelostlogician.student+json");
builder.setHeader("Accept", "application/json");
StringBuilder basicAuth = new StringBuilder();
basicAuth.append(username.getValue());
basicAuth.append(":");
basicAuth.append(password.getValue());
String basicAuthStr = basicAuth.toString();
builder.setHeader("Lambda-Authorization", "Basic " + toBase64(basicAuthStr.getBytes()));
StudentWriter studentWriter = GWT.create(StudentWriter.class);

try {
    builder.sendRequest(studentWriter.write(student), new RequestCallback() {
        public void onError(Request request, Throwable exception) {
            addItemDialog.close();
            responseDialog.open();
            loadingIcon.setVisible(false);
            responseHeading.setText("No response");
            responseLabel.setText(request.toString());
        }

        public void onResponseReceived(Request request, Response response) {
            loadingIcon.setVisible(false);
            responseDialog.open();
            loadingIcon.setVisible(false);
            responseHeading.setText("Response: " + response.getStatusCode());
            responseLabel.setText(response.getText());
        }
    });

} catch (RequestException _) {
    // Code omitted for clarity
}

选项请求得到 200 响应:

General
Request URL:https://[redacted].execute-api.eu-west-1.amazonaws.com/v1/students/4
Request Method:OPTIONS
Status Code:200 
Remote Address:54.230.9.41:443
Referrer Policy:no-referrer-when-downgrade

Response Headers
access-control-allow-headers:content-type, lambda-authorization
access-control-allow-methods:get, put
access-control-allow-origin:*
content-length:0
content-type:application/json
date:Wed, 13 Sep 2017 14:58:38 GMT
status:200
via:1.1 5db82aafd9021b07695423274288b59e.cloudfront.net (CloudFront)
x-amz-cf-id:0PoyOa6oDBSmU7iCWZyeSZFqWxZvumN8C4GtHn8rsoJK5AURbj3kxQ==
x-amzn-requestid:063270d4-9894-11e7-9d66-71b07b2689ef
x-amzn-trace-id:sampled=0;root=1-59b9479e-39be94b25784b92027fa2753
x-cache:Miss from cloudfront

Request Headers
:authority:[redacted].execute-api.eu-west-1.amazonaws.com
:method:OPTIONS
:path:/v1/students/4
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, br
accept-language:en-GB,en-US;q=0.8,en;q=0.6
access-control-request-headers:content-type,lambda-authorization
access-control-request-method:PUT
origin:http://127.0.0.1:8888
referer:http://127.0.0.1:8888/ArithmeticExerciseGeneratorClient.html
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36

…但是在收到成功的OPTIONS 响应后,它根本不发出PUT 请求。

在 Chrome 控制台中我得到:

XMLHTTPRequest 无法加载 https://[redacted]/v1/students/5。方法 预检中的 Access-Control-Allow-Methods 不允许 PUT 回应

我不明白这个错误,因为我们可以在上面显示的预检 OPTIONS 请求的 access-control-allow-methods 响应标头中看到“put”。

任何想法我做错了什么?

【问题讨论】:

  • 在你说的问题部分,“然后不继续执行所需的 PUT CORS 操作”,请考虑使用stackoverflow.com/posts/46202370/edit 编辑/更新问题以明确您的意思是什么?您可能想在浏览器 devtools 中打开 Network 窗格并重新加载并查看然后返回并在您的问题中指出 (1) 在 OPTIONS 之后浏览器真的根本不发送 PUT 请求吗?或者是吗? (2) 如果是,服务器会发送什么响应状态代码(2xx、4xx、5xx?)和标头来响应该 PUT 请求?
  • 为澄清而编辑。在 OPTIONS 之后,浏览器根本不会发送 PUT 请求。
  • 浏览器引擎没有记录任何类型的错误信息?很抱歉不熟悉 GWT 故障排除的工作原理,但是没有控制台可以记录错误吗?如果有,那里没有记录错误?您是否能够在不同的浏览器中测试某些版本的代码?火狐? (看看你是否得到相同的 no-PUT-request-sent 行为。)
  • Chrome、Safari 和 Firefox(我可以访问的浏览器)中存在问题。在 Chrome 控制台中,我得到“XMLHTTPRequest 无法加载 https://[redacted]/v1/students/5。在预检响应中 Access-Control-Allow-Methods 不允许方法 PUT”。我不明白这个错误,因为我们可以在上面的“access-control-allow-methods”中看到“put”。

标签: http gwt cors


【解决方案1】:

在 POST 响应中,允许的方法标头是

access-control-allow-methods:post, get, put

在 PUT 响应中,允许的方法头是

access-control-allow-methods:get, put

请注意,所需的方法是 POST 案例列表中的第一个,但 PUT 案例列表中的第二个。当我修改服务器以将考虑中的方法放在列表中的第一位(并且,使其区分大小写,因为 HTTP 方法名称区分大小写),然后浏览器执行所需的后续 PUT 请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 2016-12-11
    • 2018-03-29
    • 2020-09-27
    • 2017-05-25
    • 2013-07-04
    • 1970-01-01
    相关资源
    最近更新 更多