[Question] What is the expected behavior for reusing the Request body in a HTTP redirect fetch (status code 307 / 308)?
I am performing maintenance work for some some internal implementation of the fetch API for the company I am working in. Recently I discovered some bugs of that implementation related to HTTP redirect fetches with a POST request and a 3xx return code, and I am working on fixing them.
The typical use case is as follows:
- The user makes a
POSTrequest to xxx.com with a body12345 - xxx.com returns a 3XX return code and the new URL yyy.com to redirect to
- The user then requests yyy.com with the
POSTrequest and the same body12345
My major confusion arises when I discovered bugs related to the 307 and 308 return codes.
Basically, MDN says this for 307:
The only difference between 307 and 302 is that 307 guarantees that the method and the body will not be changed when the redirected request is made.
And for 308:
The request method and the body will not be altered, whereas 301 may incorrectly sometimes be changed to a GET method.
But the Fetch Spec suggests otherwise:
- If internalResponse’s status is not 303, request’s body is non-null, and request’s body’s source is null, then return a network error.
This is my interpretation:
- For 307 and 308 status codes, MDN suggests that the same method and same body shall be used for the subsequent access to the redirected URL.
- But in fetch spec, if I follow the "HTTP-redirect fetch" item 11 (as given above), then it would end up in network error.
So my question arises here: What is the expected behavior for reusing the Request body in a HTTP redirect fetch (307 / 308 return codes)?
The behavior you quote above is what happens for request body streams. And we do that because they cannot be replayed without storing the whole request body in memory, which is something we decided against doing as that would have negative performance implications in the common case.
It might not be a bad idea to add a note there clarifying that.
The behavior you quote above is what happens for request body streams. And we do that because they cannot be replayed without storing the whole request body in memory, which is something we decided against doing as that would have negative performance implications in the common case.
request’s body is non-null
In real use cases, can this body be some stateless data such as strings, ArrayBuffers or Blobs? If yes, does the same logic and decision still make sense?
Yes it can, but then its source would not be null.