Bug Tracker

Opened 8 years ago

Closed 7 years ago

Last modified 6 years ago

#11586 closed bug (duplicate)

$.ajax DELETE request not passing data parameters

Reported by: chapman.cliff@… Owned by:
Priority: low Milestone: None
Component: ajax Version: 1.7.2
Keywords: Cc: jaubourg
Blocked by: Blocking:

Description

Version 1.7.2 Firefox 11

$.ajax when type:"DELETE" will drop any data parameters involved. e.g.:

$.ajax({

type:"DELETE", data:{"var":"val"}, url:"test.php"

})

FireBug will show the request being sent with no parameters. Manually appending the parameter to the url will send correctly, e.g.:

test.php?var=val

For obvious reasons I really don't want to do that. According to this StackOverflow post, version 1.4.4 allowed for this.

http://stackoverflow.com/questions/4018982/ajax-ignoring-data-param-for-delete-requests

According to the RFC this should be perfectly allowable.

http://tools.ietf.org/html/rfc2616#section-9.7

Discussed on IRC and came to no conclusions.

Change History (22)

comment:1 Changed 8 years ago by dmethvin

Component: unfiledajax
Priority: undecidedlow
Status: newopen

I dunno, the RFC isn't that clear about whether the args should be on the URL or in an entity body. Further info:

http://stackoverflow.com/questions/299628/is-an-entity-body-allowed-for-an-http-delete-request

http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-19#page-23

If the method CAN accept an entity body, then the data should be going there and not the URL. Perhaps the data is going into an entity body but it's being thrown away by Firefox?

comment:2 Changed 8 years ago by chapman.cliff@…

I'm fairly new to JavaScript and am investigating how to set up an AJAX request in raw JS to test it outside of jQuery. I would still point out that a commit (made by yourself) a year ago was meant to allow this, but current functionality shows it is not working.

https://github.com/jquery/jquery/commit/09022e0b09db71259751e7146bb64727615028af

comment:3 Changed 8 years ago by dmethvin

OK, then, thanks for the reminder! Your post above seems to indicate you're expecting the data to be on the URL. If my post from a year ago is correct (and it seems to agree with those links) then the data should be in the entity body and not the URL. Is that what you expected? Are you seeing Firefox send it in the entity body ("POST data")?

comment:4 Changed 8 years ago by jaubourg

Yep, there seems to be some confusion here, seeing that rnoContent did *not* change: https://github.com/jquery/jquery/blob/master/src/ajax.js#L11

comment:5 Changed 8 years ago by anonymous

I managed to get a mock up written by manually creating am XMLHttpRequest, FireBug was showing the data being sent in the body and NOT the URL. The URL system simply worked.. somewhat, with minor modification on the server side.

So yes, sending the data in the entity body seems to be the correct route.

comment:6 Changed 8 years ago by dmethvin

Resolution: worksforme
Status: openclosed

Sweet, it's working then.

comment:7 Changed 7 years ago by jhancockdarwin@…

I believe that this ticket should be reopened.

IIS/MVC.net/ASP.NET cannot parse parameters passed in the body of DELETE request.

Google web hosting returns BADREQUEST. Amazon hosting returns BADREQUEST

The RFC clearly states that all delete values should be passed in the URI.

jQuery should be converting the data passed to the URI.

comment:8 Changed 7 years ago by dmethvin

@jhancockdarwin can you quote the specific part of the RFC? My impression was that DELETE could have a body. As things stand now you can encode parameters in the URL yourself, but if we reverse it there would be no way to send a body.

comment:9 Changed 7 years ago by jhancockdarwin@…

9.7 DELETE

The DELETE method requests that the origin server delete the resource identified by the Request-URI. ....

Note that it clearly states that the resource must be identified by the URI, not the body. This is why most major servers will not allow a body on a DELETE request and either ignore it, or throw an error (and firebug does the right thing by ignoring it)

DELETE works exactly the same as GET. All data should be passed as parameters on the URI as specified by the RFC.

comment:10 Changed 7 years ago by dmethvin

Resolution: worksforme
Status: closedreopened

Just to link, you're quoting http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7

I'll reopen, but at this point it's too late for 1.8 I think.

Last edited 7 years ago by dmethvin (previous) (diff)

comment:11 Changed 7 years ago by dmethvin

Cc: jaubourg added
Status: reopenedopen

comment:12 Changed 7 years ago by Dave Methvin

Resolution: fixed
Status: openclosed

Fix #11586. Ajax DELETE ain't got no body, so data goes to its URL.

Changeset: c01e022f33575ed45fb8da65be756fc464d40a24

comment:13 Changed 7 years ago by jaubourg

We're going back and forth here, this is breaking since we did it that way purposedly: http://bugs.jquery.com/ticket/7285

It seems to me the previous behaviour was better. The spec doesn't say there shouldn't be a body, it says the resource should be identified in the URI which doesn't forbid to add additional data in the body. That some implementations decide to ignore it is irrelevant here.

With the previous behaviour, you could handle the identification within the URL and give a body. Now we're just being more strict than the standard, which never ended well for us ;)

comment:14 Changed 7 years ago by dmethvin

@jaubourg, your memory and/or search skills exceed mine. It seems that according to this ticket several very popular implementations specifically forbid a body so perhaps that is a good enough reason?

comment:15 Changed 7 years ago by jaubourg

Except said implementations are not standard: they shouldn't break on a DELETE with a body, they simply can (and probably should) ignore said body.

All I'm saying is that the previous fix allowed DELETE requests with or without a body, which is standard compliant. The fix in this ticket specifically forbids DELETE requests with a body and doesn't add any actual feature (you could already add data to the URL manually).

I'd say the safest way is probably to keep the less restrictive approach. There is more to data you can send using a request than resource identification alone, timing, security and debugging info come to mind (especially for a destructive operation such as a DELETE).

Let's not paint ourselves in a corner with the risk of going back and forth again in yet another minor version. If we want to look into this seriously, let's 1.9-discuss it.

(Just some quick searching in the tracker btw, because it rang a bell. So half-memory/half-search I guess ;)

comment:16 Changed 7 years ago by Dave Methvin

Revert "Fix #11586. Ajax DELETE ain't got no body, so data goes to its URL."

This reverts commit c01e022f33575ed45fb8da65be756fc464d40a24.

We actually changed DELETE to accept a body on purpose, see http://bugs.jquery.com/ticket/7285 .

Changeset: 05337e78fa68aac3a3d703d7cc59f145f13ea779

comment:17 Changed 7 years ago by dmethvin

Agreed, jaubourg. If I had seen the earlier ticket I wouldn't have pursued this, so I've backed it out. Anyone who wants to send the DELETE request in the URL already has the tools to do so.

Can you review the tickets in your usual haunts and see if any need changes? You can probably do that faster and better than I can. I'm only leaving tickets open if I think they need action, so this ticket fit into that category.

comment:18 Changed 7 years ago by jaubourg

Resolution: fixed
Status: closedreopened

I'll try to be more attentive next time. I see the ticket was created on April the 12th (my birthday) which could explain a lot ;)

I also tend to leave tickets open in case someone else would chime in, but I think it's probably a mistake and I should start closing bugs more often and pre-emptively. We can always re-open them anyway.

Sorry about my missing this one earlier btw.

comment:19 Changed 7 years ago by jaubourg

Resolution: duplicate
Status: reopenedclosed

Duplicate of #7285.

comment:20 Changed 6 years ago by bharbulot

While we can discussed whether a body is allowed at all in a DELETE request, it doesn't make any sense to do so.

The StackOverflow question used to justify this change in #7285 states it clearly:

the request URI should completely identify the resource to delete.

This is also quite clearly in the HTTP specification: http://tools.ietf.org/html/rfc2616#section-9.7:

The DELETE method requests that the origin server delete the resource identified by the Request-URI.

Therefore, you can't put anything that's going to help identify what to delete in the body.

If you send a DELETE request to http://example.com/user.php, whether the content of the body is id=1 or id=2 doesn't matter, it's the resource solely identified by http://example.com/user.php that should be deleted.

While the HTTP specification may tolerate a body in a DELETE request, the spec doesn't really leave much room to do anything with it. (Metadata belongs to the headers anyway.)

This is the same argument as for HTTP GET. Quoting Roy Fielding:

Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in mind. Server semantics for GET, however, are restricted such that a body, if any, has no semantic meaning to the request. The requirements on parsing are separate from the requirements on method semantics.

So, yes, you can send a body with GET, and no, it is never useful to do so.

This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).

In contrast, http://example.com/user.php?id=1 is a different URI from http://example.com/user.php?id=2, which identifies a different resource.

Hence, it would make much more sense to pass the data as query parameters (like GET does) instead of passing them in the body.

comment:21 Changed 6 years ago by ron.kleinman@…

So I've worked my way through the entire path and I still don't know ... if a Delete request has a body, is there a way for the service code to see it?

We are designing an industry-wide REST standard and at this point have been told in order to have a single request delete multiple objects who's refIds are in a list we should:

  1. Put the list as query parameters in the URL
  2. Use X-HTTP-Method-Override set to Delete, in a POST, where the body contains the list and the HTTP field says it's really a delete.
  3. Use a 2-step approach - send the list as a post, get back a URL and then send a delete to that URL
  4. Put the list in the payload of the delete and assume the service accepts it, because most development platforms today accept it.

Unfortunately we need to standardize on one of these for all adapters, and are probably going with #4. I need to know if your service platform will support that or has to be explicitly flagged. Much thanks for any response or clarification here.

comment:22 Changed 6 years ago by bryan.dollery@…

So, I have to delete an object which is under the control of an optimistic locking protocol.

As you can imagine, every change on the object updates its version, and when I try to update that object I have to tell the server which version I have, so it knows that I'm dealing with the latest information before making my change, or it informs me that my object is out of date and leaves me to refresh it if I please.

So, the version shouldn't be part of the URI, because the object's identity isn't changing. I don't think it belongs in the query string, because I'm issuing updates against a specific object, not search results, so the query string shouldn't exist. I can put the version in the headers, but the headers are used by the server for routing and meta-processing and probably shouldn't be passed into the business logic. The only place left is to have the object I'm modifying sent along with the delete command. Then the server is free to use it to determine the version any way it wishes.

Or, is this all wrong? Only, I can't do this at the moment -- I have to hack the version into the meta-data somehow.

Note: See TracTickets for help on using tickets.