-
Notifications
You must be signed in to change notification settings - Fork 340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request with GET/HEAD method cannot have body. #551
Comments
HTTP allows a request body on GETs syntactically so that message parsing is generic; it doesn't say that a body has any meaning on a GET. So, anyone using a body on a GET is effectively "off the reservation"; they're not longer using HTTP, but defining their own private protocol. Since Fetch is an API for HTTP, it's entirely reasonable for it not to allow this. More practically, using bodies on GETs tends to trigger interop problems with proxies, CDNs, servers, etc. While it might work in the lab or even on the Internet under controlled conditions, using it at scale is very likely to bump into this. For example, users who have virus scanning proxies are likely to have problems, since they tend to have very conservative implementations. |
Mark, thanks for your response. This isn't about me or any individual wanting to use a body on a GET. It's about the fact that it is used in industry which you can see in the ElasticSearch documentation which I linked in my first post. ElasticSearch is used at scale in industry. Don't try to convince me not to use it. Convince people like Elastic company not to use it. My point is, I don't think additional rules should be added to a spec even in parts where the spec isn't explicitly clear, especially when it can be shown that it limits certain industry applications. |
If we changed how we use HTTP (or TCP, or any other protocol) to accommodate every abuse in "industry" like this, we'd quickly lose all of the value of having a shared protocol. Get them to fix their software, don't try to convince everyone else to accommodate their non-standard use. |
Duplicate of #83. As far as I know nothing changed since then. |
Doing something that is allowed within the HTTP spec is hardly abuse. It seems odd that the creators of this get to dictate how APIs should and should not work...
Well, you should take your own words to heart because what people are trying to accomplish is definitely according to standard... |
So far I could reference the following arguments against the addition (in fact it is a suppression) of this:
Please consider that all people that wrote messages about this concern aren't trolling or trying to enforce a point of view. Sending a GET Request with a body is used widely in the industry and is not explicitly forbidden by the RFC. Refusing to allow it for the reasons that I listed is just being conservative and reactionary. It does not promote progress in the slightest. |
Elasticsearch rest api requires sending a body with a GET. Please at least provide an option for disabling this. Sending a body with GET is part of the standard. |
If some specific platforms/frameworks reject handling GET/HEAD requests with a body, those who use them will work around by making bodyless GET/HEAD requests or switching to standard compliant platforms/frameworks. There are already platforms/frameworks handling GET/HEAD requests with a body, some of them also handle security and caching. It isn't right to enforce non-standard behavior on the fetch API. |
I recommend reading #83 for some background as to why this is not that simple. But really, if you can convince browsers to add this and overcome the hurdles discussed there, it'd happen. Advocacy here is unlikely to help with that though. |
(Also, |
@annevk Using a non-standard HTTP method is not an acceptable solution to a non-standard HTTP behavior. Browsers follows the Fetch API standard, and suggesting otherwise is a bad call. There is a HTTP standard. There is Fetch API standard. Fetch API works using HTTP, so it should be compliant with HTTP standard unless it cause a security breach. |
Can you be more specific about this? Which unique considerations are there for the browser application that makes it so difficult to allow this in the Fetch standard? I mean, keep in mind that if somebody really wants to send a GET with a body, they can do it with any other application. The issue with that is many developers want to implement internal tools as browser apps because it is convenient and safe. |
It's as simple as allowing new things to be send to unsuspecting servers. Non-browser applications might not necessarily have the same state or run on the user's computer and therefore have access to the user's private network. The bigger problem is lack of implementer interest though, as noted above. |
I agreed with the fact that it is not really a standard way and import https from 'https';
import http from 'http';
const requestWithBody = (body, options = {}) => {
return new Promise((resolve, reject) => {
const callback = function (response) {
let str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
resolve(JSON.parse(str));
});
};
const req = (options.protocol === 'https:' ? https : http).request(options, callback);
req.on('error', (e) => {
reject(e);
});
req.write(body);
req.end();
});
};
// API call in async function
const body = JSON.stringify({ a: 1});
const result = await requestWithBody(body, options = {
host: 'localhost',
port: '3000',
protocol: 'http:', // or 'https:'
path: '/path',
method: 'GET',
headers: {
'content-type': 'application/json',
'Content-Length': body.length
}
};
) |
This might bring some clarity. Not that favors one side or the other but at least brings context to the conversation. |
From what I read in this issue and the associated comments, I see that the refusal is based on a theoretical vulnerability. I have put a great deal of thought about this but I fail to see how sending a body with a I also read the RFC again - and the comments on the Elasticsearch issue are pretty clear about that as well - I still fail to see where the RFC forbids to have a body using a |
httpwg/http-core#202 is something of a focal point for this conversation, and was resolved by updating the latest HTTP spec draft in httpwg/http-core@f34f677 to include the explanation you're asking for:
It's not so much that HTTP clients are strictly forbidden from including content in a GET request, it's that HTTP servers may not use such content. |
So basically they're asking for people to bypass the standard completely and only use POST for everything just so they could use clean payloads without obstacles. |
Just a question here, not advocating for any side in the debate :) I'm a bit confused if this is a restriction in the Fetch specification or in Fetch implementations. If it's a spec thing, could someone point me to the relevant lines in https://fetch.spec.whatwg.org/? Tried to find what methods should support bodies but was unable to. |
Rather than fix the implementation, they opted to subset the HTTP specification to fit the implementation of fetch(). Rule 33 of "The new Request(...) constructor steps are:" https://fetch.spec.whatwg.org/#dom-request
Which prevents doing clean call with complex nested structures like the fake code below.
If you wanted to make a proper API to handle front & back interactions, you can't. |
Every time I encounter a |
More frustrating the language change on the HTTP spec to say "should not" was supposed to be accompanied by a new method Right now we're in a situation where the best practice for when your query params on a |
The language change was only due to the WHATWG not wanting to admit they made a mistake so the standard got modified instead. There is nothing more to it. |
The RFC should be changed, everyone needs it. I need to make complex queries, so I need to use methods other than GET, does not make sense... Whoever takes care of this RFC doesn't know what the programmer suffers. |
At the very least, the standard should add new alternative standard verbs that are similar to GET and HEAD in meaning, but support having a body. |
Including a body in a GET request, is already supported in the standard |
Indeed it is, but the whatwg seems hellbent in stubornly rejecting that standard use because it could mess up with legacy code that assume otherwise. Hence why the least would be to do the same thing that was done with HTTP, when codes 307/308 were added as alternative to 301/302. |
Legacy code assuming get requests use no body, would not use body in their get requests. So how is supporting body for get requests going to break legacy code? |
Their reasonning is that some caching systems could cache the response ignoring the body when making an identifier rather than a using a hash of the full request with the body too. And they consider that to be enough to then edit the fetch() standard to forbid a body with HEAD/GET. |
I guess I'll just use a POST when I want to retrieve entities based on structured data. Thanks guys. Doing good work over here👍 |
There is a decade old draft for QUERY, an equivalent of GET with a body. It's barely touched upon. From time to time it's brought back from the bin. Current draft Timeline |
curl allows get with a body. Now I HAVE TO switch from fetch to another library because fetch does not allow this. It is not my fault, it is the server's fault, and I cannot change how the server works. |
A library for the browser? I do not think any can support that if fetch does not. |
library like axios use xmlrequest, does not rely on fetch. |
You can easily circumvent |
this has not been fixed ... I cant send body using get method using fetch ... thank you so much for the lessons on fake security ... now please enable sending body through get request. |
Seriously!!!! I honestly can't believe I read all this, to conclude that Just to annoy such a dumb ass decision, I am going to make everything This idea seems like a NuGet package just waiting to be made. Maybe change the naming convention from "Http" to "Rest": RestClient, RestGet, RestPut, RestPost, RestDelete... that way we can always send a body while still fulfilling our desires as developers —after all, we break semantics all the time anyway because of dumb stuff like this and make our own. With some time get Swagger updated with this concept in mind. In the end, we will get what we want. |
+1 enable GET bodies please. Even if it's not strictly spec'd, it's as good as an undocumented industry standard in 2024. You can add Akamai, Palo Alto, and ServiceNOW to the list of platforms that support HTTP GET body parameters in their APIs. There are other large players doing the same. The mislabeling of such practice as 'abuse' is wishful thinking, IMO. I stumbled across this debacle when trying to migrate from jQuery's $.ajax() into a vanilla-JS solution, considering it's 2024 and jQ has been all-but-replaced by modern JS: see youmightnotneedjquery[.]com. Instead of 'muddying' my JS GET requests with mile-long parameters visible in the URL, I much prefer the encapsulation of parameters in the request body similar to a POST request. That said, I do NOT support the concept of security through obscurity. Instead, this approach makes the UX cleaner without mandating server rewrite rules or other 'after the fact' changes. All available web server offerings + PHP's native interpreter already successfully handle this data today, regardless if URL-encoded or request body encapsulated. You've created a roadblock where one doesn't need to exist in order to argue standards semantics. Can you imagine the backlash in the prime of jQuery if the devs had said, "No, I want you to do it this way"? |
Doesn't this straight up break the web even? What if you have to send a GET request along with data that exceeds 2048 characters? Can't even fit everything in the URL, we'll have to put data in headers as key value pairs! /s |
I think this shows how absurd this position that GET should not have body is - because you can always move body to headers and that is allowed. It is just uglier. |
Reference: whatwg/fetch#551 Certain interpretations and implementations of the IETF RFC do not support GET/HEAD HTTP method request body content. The request body checking is extraneous for the purpose of this testing, which is only intended for just the HTTP methods themselves, so just removing it.
This comment was marked as duplicate.
This comment was marked as duplicate.
Another point that shows how absurd this is: I'm making a GUI rest client as a convenient testing tool embedded in an IDE. So I'm not even the one deciding on the request or its semantics, I'm just providing a tool for others to use. And now, because of this, I basically have to hand this hostage situation down to everyone using my plugin and suddenly I - who is in no position to interfere with what my users wanna do with the client - have to enforce non-standard behavior when such a plugin should be as flexible as it can be. Not allowing GET bodies is not rooted in caution. It's certainly not rooted in standard compliance. By now, I'm pretty confident it's rooted in stubbornness and pride. If it breaks legacy code - don't use GET bodies when interacting with those systems. It's that easy. |
This works with Laravel (or any server implementing this)
|
I ran into this restriction while building HTTP functions for a library. I think this should be reconsidered because sometimes people actually use the body in a GET request. Notably, ElasticSearch can use it for queries. It can use the querystring instead, but that can be pretty cumbersome which is why it also accepts a body for GET queries.
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html
Since I'm making a library I want to allow everything within the specification of HTTP but apparently fetch has its own rules, and as you can see it's possible for that to interfere with using an API._
You'd think this is an edge case, but if it interferes with something like ElasticSearch maybe it's not an edge case._
The text was updated successfully, but these errors were encountered: