I have a question for a specific CORS-related problem: Having set up server-side CORS configuration on JAX-RS such that it works properly for GET, PUT, and POST, I don't manage to get it to work with DELETE requests.
I have set up JAX-RS request / response filters as explained here and here:
For the "preflight OPTIONS" requests:
@Provider
@PreMatching
public class CorsOptionsPreflightRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestCtx) throws IOException {
if (requestCtx.getRequest().getMethod().equals("OPTIONS")) {
requestCtx.abortWith(Response.status(Response.Status.OK).build());
}
}
}
For actual CORS handling:
@Provider
@PreMatching
public class CorsResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestCtx, ContainerResponseContext responseCtx) throws IOException {
responseCtx.getHeaders().add("Access-Control-Allow-Origin", "*");
responseCtx.getHeaders().add("Access-Control-Allow-Credentials", "true");
responseCtx.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
responseCtx.getHeaders().addAll("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
}
}
I'm testing on Google Chrome with the CORS plugin activated.
Again, GET, PUT, and POST requests work perfectly, but DELETE yields the error:
XMLHttpRequest cannot load http://localhost:8080/serverApplication/persons/3. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. The response had HTTP status code 400.
Note: I'm only interested in solutions with work with the JAX-RS standard, no vendor-specific (e.g. RESTeasy, Spring) solution.
What am I missing?
edit 1:
Also, when setting a debug breakpoint in CorsResponseFilter#filter()
, it is never reached on a DELETE request, but on GET / POST requests it is. Also DELETE works well when executing it from a curl
console.
edit 2:
The client is written in Restangular.
Sorry, wrong alert.
I found out that much to my amazement the actual problem lies within the client which is written in Restangular.
The "magical" solution is to tell Restangular to send DELETE requests without a body, as explained in this issue:
RestangularProvider.setRequestInterceptor(function(elem, operation) {
if (operation === "remove") {
return undefined;
}
return elem;
})
Otherwise, DELETE requests trigger a 400 error which I suspect the browser is wrongly interpreting as a CORS error, thus outputting above CORS-related error message in the console.