-1

I have a simple Java web service that handles my SQL method with Jersey. The HTTP call is from an Angular project. GET and POST are working fine, but when I try a DELETE, I get an HTTP 405 error.

This is how I call the method in Angular:

deletaDados(id){     
    this.service.deleteData(id)      
}

+

deleteData(id){    
    return this.http.delete(`${this.api}/${id}`).subscribe((res) => {
});;

}

And this is the DELETE Java method:

@DELETE
@Path("{id}/")
public Response delete(@PathParam("id") long id) throws SQLException, ClassNotFoundException{
    ofertaDAO dao = new ofertaDAO();
    dao.delete(id);
    return Response
        .status(200)
        .header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Headers", "origin, content-type,  accept, authorization")
        .header("Access-Control-Allow-Credentials", "true")
        .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
        .header("Access-Control-Max-Age", "1209600")
        .entity(id)
        .build();
}

Seem right... No idea why I'm getting the 405 error.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197

1 Answers1

1

If the DELETE coming from your frontend JavaScript code is a cross-origin request, then your browser (automatically on its own) will send a CORS preflight OPTIONS request first.

So it seems like the 405 you’re seeing may be the response to that preflight OPTIONS request — and if so, then you’ll need to have an explicit OPTIONS handler in your server-side Java code.

That OPTIONS handler should just send back a response with a 200 status and the necessary CORS headers, with no response body; so, something like this:

@OPTIONS
public Response options(){
  return Response
      .status(200)
      .header("Access-Control-Allow-Origin", "*")
      .header("Access-Control-Allow-Headers", "origin, content-type,  accept, authorization")
      .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
      .header("Access-Control-Max-Age", "1209600")
      .build();
}

Incidentally, also note that for the Access-Control-Max-Age response header there’s probably not much point in setting a value that’s any greater than 600 (10 minutes) — because if you do set a value greater than that for it, Chrome will just clamp it to 600 anyway.

And as far as why you don’t also run into that 405 when you send a GET or POST from your frontend JavaScript code, the reason is that the GET and POST requests your code is sending don’t have characteristics (such as custom headers) that’ll trigger your browser to do a preflight. But cross-origin DELETE requests always trigger browsers to do a preflight.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
  • Sorry i didnt understand what i have to do, isnt my response with 200 status already being called on my delete method? Yes the http call is coming from a angular project(edited the question).Not sure what ur suggesting, can u explain again? – Daniel Bezerra De Menezes Oct 25 '17 at 10:10
  • The server code for your DELETE method looks fine & should work when the browser actually sends the DELETE request from your code. But when things work correctly for a cross-origin DELETE, the browser makes *two* requests: first on its own the browser makes the preflight OPTIONS request, & the if the server sends the right response for that preflight OPTIONS request, then next the browser sends the DELETE request from your code. So your server needs to handle those two separate requests: It first needs to respond with a 200 for the OPTIONS, then next needs to respond with a 200 to the DELETE. – sideshowbarker Oct 25 '17 at 11:32