AndroidAsync
AndroidAsync copied to clipboard
setup server to response to CORS `OPTIONS` request
How to make Async-Server to response below HTTP headers:
OPTIONS http://localhost:3048/Token HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Access-Control-Request-Method: POST
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Origin: http://localhost:2757
Referer: http://localhost:2757/Auth/login
... ...
This is the chrome Preflight OPTIONS request header, how to setup server to response to this OPTIONS
request?
I've found the solution, as below:
void setResponseHeaders(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
Headers allHeaders = response.getHeaders();
Headers reqHeaders = request.getHeaders();
String corsHeaders = reqHeaders.get("access-control-request-headers");
if(corsHeaders!=null) {
// common headers
allHeaders.set("Access-Control-Allow-Origin", "*");
allHeaders.set("Access-Control-Allow-Credentials", "true");
allHeaders.set("Access-Control-Allow-Headers", corsHeaders);
allHeaders.set("Access-Control-Allow-Methods", "HEAD,OPTIONS,GET,POST,PUT,PATCH,DELETE,CONNECT");
allHeaders.set("Access-Control-Max-Age", "86400");
}
}
... ...
server.addAction("OPTIONS",".+", new HttpServerRequestCallback() {
@Override
public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
setResponseHeaders(request, response, false);
response.send("ok");
}
});
Just tested seems worked here.
Two big images for showing a successful demo:
I took a whole night to fix this issue. Now the code followed works for Chrome and Axios with/without Cookie for GET, POST application/json, POST www-form-url-encoded and POST form-data:
private void startServer(int port) {
server.addAction("OPTIONS", "[\\d\\D]*", this); //add OPTIONS
// server.get("[\\d\\D]*", this);
// server.post("[\\d\\D]*", this);
server.get("/", this);
server.post("/method/list", this);
server.post("/method/invoke", this);
server.listen(mAsyncServer, port);
}
@Override
public void onRequest(final AsyncHttpServerRequest asyncHttpServerRequest, final AsyncHttpServerResponse asyncHttpServerResponse) {
Headers allHeaders = asyncHttpServerResponse.getHeaders();
Headers reqHeaders = asyncHttpServerRequest.getHeaders();
String corsHeaders = reqHeaders.get("access-control-request-headers");
String corsMethod = reqHeaders.get("access-control-request-method");
String origin = reqHeaders.get("origin");
String cookie = reqHeaders.get("cookie");
//Access-Control-Allow-Credentials: true is conflict with Access-Control-Allow-Origin: * , you need to put origin value
allHeaders.set("Access-Control-Allow-Origin", TextUtils.isEmpty(origin) ? "*" : origin);
allHeaders.set("Access-Control-Allow-Credentials", "true");
allHeaders.set("Access-Control-Allow-Headers", TextUtils.isEmpty(corsHeaders) ? "*" : corsHeaders);
allHeaders.set("Access-Control-Allow-Methods", TextUtils.isEmpty(corsMethod) ? "*" : corsMethod);
allHeaders.set("Access-Control-Max-Age", "86400");
if (TextUtils.isEmpty(cookie) == false) {
allHeaders.set("Set-Cookie", cookie + System.currentTimeMillis());
}
if ("OPTIONS".toLowerCase().equals(asyncHttpServerRequest.getMethod().toLowerCase())) {
asyncHttpServerResponse.send("application/json; charset=utf-8", "{}");
return;
}
//TODO
}
Other browsers and http libraries haven't been tested yet, but most of them should pass the tests.
see the complete file by the link followed: https://github.com/APIJSON/APIJSON/blob/master/APIJSON-Android/APIJSONTest/app/src/main/java/apijson/demo/ui/UnitActivity.java
If there is anything wrong, please reply me, thank you~