17

I'm using expressjs and the body-parser middleware.

This is how I initiate it:

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

From the client I'm sending a DELETE request and when I try to pick it up from the server side I get an empty object:

app.delete('/', function(req, res) {
    console.log(util.inspect(req.body)); //outputs {}
    //some more code
});

however when I send it with a POST I get what I need:

app.post('/delete', function(req, res) {
    console.log(util.inspect(req.body)); //outputs { mid: 'ffw1aNh2' }
    //some more code
});

It is worth noting that I don't change anything on the client side (angularjs) but the method and the url and the firefox network debugger shows the data being sent in both situations.

What am missing here? Why am I getting an empty body object on a delete method?

Tom Klino
  • 2,358
  • 5
  • 35
  • 60
  • [This](http://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request) may be of interest. – JAM Jun 13 '16 at 17:59
  • It doesn't really help me understand. It says there that DELETE requests have a body, and moreso, that it is not discourged or disallowed. So it's even more of a reason to think that the body object should not be empty, no? – Tom Klino Jun 13 '16 at 18:03
  • `body-parser` doesn't care about the HTTP method being used AFAIK, and it should work just fine with `DELETE`. Does the `Content-Type` header of the _request_ look okay? – robertklep Jun 13 '16 at 18:13
  • Now that I check, there is a difference. When I'm using POST the content-type is `application/json` and when using DELETE it is `text/plain` – Tom Klino Jun 13 '16 at 18:21
  • @TomKlino that's your problem :) `body-parser` is only looking for JSON or URL-encoded body data, not `text/plain`. – robertklep Jun 13 '16 at 18:21
  • BTW, although I don't want to start a too long discussion in the comment section, does angualr's behaviour implies that a best practice would have been to send that id via the url (like `$http.delete("/mid/" + mid)`)? – Tom Klino Jun 13 '16 at 18:32

1 Answers1

25

The $http service source code, a DELETE request using $http does not allow for data to be sent in the body of the request.

The spec for a DELETE request is somewhat vague on whether or not a request body should be allowed, but Angular does not support it.

The only methods that allow for request bodies are POST, PUT, and PATCH. So the problem is not anywhere in your code, its in Angular's $http service.

Use this

$httpProvider.defaults.headers.delete = { "Content-Type": "application/json;charset=utf-8" };

and then

$http.delete(url, { data: data })

Harshit Anand
  • 602
  • 9
  • 13
  • I respectfully disagree on the base of plain facts. as I stated in my question, the Firefox network debugger clearly shows my data being sent. – Tom Klino Jun 13 '16 at 18:19
  • ...But with the wrong header! That did fix it. Although, I had to drop the "Provider" just `$http.defaults...` – Tom Klino Jun 13 '16 at 18:25
  • $httpProvider is to be used in your config this way it is in a central place for your app – jgerstle Jun 11 '17 at 08:46