0

While creating a REST service with NodeJS I ran into a problem. The DELETE request gets interpreted as GET on the server side.

This may be some security feature to avoid data loss, but this moment I figure out what is wrong.

I am using express 4.13.4, es6-promise 4.0.5 and jquery 3.1.1

Client side:

deleteBear: function (bear) {
    console.log("DEL REQ","http://domain.com/api/v1/" + bear._id);//CORRECT
    var Promise = promise.Promise;
    return new Promise(function (resolve, reject) {
        $.ajax({
            url: "http://domain.com/api/v1/" + bear._id,
            method: "DELETE",
            dataType: "jsonp",
            xhrFields: {
                withCredentials: false
            },
            headers: {
              "Access-Control-Allow-Origin: ": "*",
              "Access-Control-Allow-Methods: ": "DELETE",
              "Access-Control-Allow-Headers: ": "Authorization",
              "X-HTTP-Method-Override": "DELETE",
            },
            success: function(json){
                console.log("OK",json);//OK GETS CALLED
                resolve(json);
            },
            error: function(err){
                console.log("ERR",err);
                reject(err);
            },
        });
    });
}

Server side:

router.route('/api/v1/:id')
/* GET request. */
.get(function(req, res) {
    console.log("GET REQUEST");//THIS GETS CALLED INSTEAD OF DELETE

    res.statusCode = 200;
    res.jsonp("OK");
})
/* DELETE request. */
.delete(function(req, res) {
    console.log("DELETE REQUEST");

    res.statusCode = 200;
    res.jsonp("OK");
});

No error gets shown in client console:

DEL REQ http://domain.com/api/v1/58060570b45c9340e916be90
OK OK

The server console shows GET being called instead of DELETE:

GET REQUEST
GET /api/v1/58060570b45c9340e916be90?callback=jQuery31107932283916014113_1476822027044&_=1476822027046 200 26.929 ms - 652976
Peter G.
  • 7,816
  • 20
  • 80
  • 154
  • 5
    There is no such thing as a JSONP `DELETE` request. How can you append a ` – apsillers Oct 18 '16 at 19:27
  • I'm guessing you meant to have the *server* send those `Access-Control-*` headers, and have the client not use `type: "jsonp"`. Note that since a DELETE method makes a cross-origin request non-simple, you will need to also send those headers in response to the preflight OPTIONS request that will hit the server as well. (See [How does Access-Control-Allow-Origin header work?](http://stackoverflow.com/a/10636765/710446)) – apsillers Oct 18 '16 at 19:29
  • Are you using the `method-override` package? Express won't interpret the extra verbs without it running as middleware – Dave V Oct 18 '16 at 19:31
  • The `jsonp` was used to get through the **same origin policy** warning. Losing `DELETE` was a side effect... A soution could be to remove the jsonp but then the warning shows up again. – Peter G. Oct 18 '16 at 19:32
  • @DaveV I'm not using `method-override`, I will try this option – Peter G. Oct 18 '16 at 19:34
  • 3
    Since you seem to control the server, the best option is to have the server send CORS headers (and ***not*** have the client do it, which will cause CORS to fail, due to non-whitelisted request headers). – apsillers Oct 18 '16 at 19:35
  • @PeterGerhat yeah give that a shot, just install that package then in your express config do an `app.use(methodOverride())` or whatever you called it when you required it – Dave V Oct 18 '16 at 19:36
  • Here's my first feedback after trying the suggestions, some of the headers couldn't be set `Refused to set unsafe header "Host"` and `Refused to set unsafe header "Origin"`. As I look at your comment, it looks like the server has to initiate the CORS request. – Peter G. Oct 18 '16 at 19:55
  • @DaveV The DELETE method works normally when called from elsewhere (e.g. Postman). However, the client ends up calling GET by using the exact same URL. – Peter G. Oct 18 '16 at 20:13
  • What are you using on the client side to send the `DELETE` request? – Dave V Oct 18 '16 at 20:15
  • jquery 3.1.1 - the code is already provided in the question – Peter G. Oct 18 '16 at 20:19
  • @aspillers Your comments deserve to be in an answer. – Emile Bergeron Oct 18 '16 at 20:39
  • @PeterGerhat Where are you trying to set `Origin` and `Host`? `Origin` and `Host` and both set by the browser automatically when sending a request (so your script should not and cannot set them to some other value), and they are not response headers, so the server shouldn't send them. If your client is still sending GET requests, it sounds like your script is still using `type: "jsonp"`, which can only operate by GET requests. – apsillers Oct 18 '16 at 22:10

0 Answers0