简体   繁体   中英

POST GWT CORS request works but PUT CORS request doesn't

I'm writing a GWT frontend for a personal project, and I'm having problems with some HTTP requests. When I do a CORS POST request, it works fine

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
}

The options request gets a 200 response (chrome network inspection below):

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

and then the POST request occurs as expected

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}

Unfortunately, a PUT request to a very similar resource, on the same server, doesn't. The code is almost identical:

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
}

The options request gets a 200 response:

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

…but after receiving a successful OPTIONS response, it does not make the PUT request at all.

In the Chrome console I get:

XMLHTTPRequest cannot load https://[redacted]/v1/students/5 . Method PUT is not allowed by Access-Control-Allow-Methods in preflight response

I don't understand that error, given that we can see " put " in the access-control-allow-methods response header for the preflight OPTIONS request shown above.

Any ideas what I'm doing wrong?

In the POST response, the allowed methods header is

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

In the PUT response, the allowed methods header is

access-control-allow-methods:get, put

Note that the required method is the first in the list of the POST case, but second in the list in the PUT case. When I modified the server to put the method under consideration first in the list (and, also, to make it case sensitive, because HTTP method names are case sensitive), the browser then performed the required followup PUT request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM