The client-side library (haven't verified server-side yet) is following 302 redirects on POST. According to the spec:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
Unfortunately, I can't even disable this with a .redirects(0) as:
superagent.post(...).redirects is not a function
Agreed that's a protocol violation and superagent definitely shouldn't be doing this. Could you help by writing a test or maybe fixing the issue?
I've checked this. Superagent doesn't re-send POST, but changes request method to GET on 301, 302 and 303. I think that's fine, and follows the current HTTP RFC:
Note: For historical reasons, a user agent MAY change the request
method from POST to GET for the subsequent request. If this
behavior is undesired, the 307 (Temporary Redirect) status code
can be used instead.
I do not agree with your conclusions and this issue should be reopened imo. My reference is this https://tools.ietf.org/html/rfc2616#section-10.3.3.
RFC addresses two distinct problems:
As far I understood, as a response to POST requests, 302 says that
Hence, superagent must not redirect automatically, but, if redirect is confirmed by the user, it can resend the request using GET instead of POST.
EDIT
Apparently it depends on XHR implementation/specification. One of the reasons why ajax sucks. :-P
RFC 2616 has been obsoleted and should not be used as a reference any more. The current HTTP RFC clarified this, and we follow the current recommended behavior for HTTP.
@pornel (How) can I log the redirects happening?
Use .on('redirect', callback)
@pornel the response.text in the callback is undefined for redirect events.
Do you know how I can log the _exact_ http response?
Bodies of redirect responses are supposed to be only a fallback for clients that don't support redirects, so we don't parse them.
@pornel sorry, I don't mean the body, but the actual reply in http format.
For example (I made this up):
HTTP/1.1 301
Date: Mon, 22 May 2017 12:25:30 GMT
Server: Apache
Location: http://www.foo.bar
Content-Length: 100
Connection: close
Content-Type: text/html; charset=utf-8
Can we retrieve this, or is superagent skipping this when status is 30x?
Superagent doesn't have raw bytes of the response. It uses Node's request, which is higher-level than that. For that I'd recommend wireshark, tcpdump, etc.
I don't remember off top of my head whether we set headers object, but it might be there.
@pornel I can indeed get close using headers or rawHeaders. Also status works. I can't seem to find the protocol declaration though, e.g. HTTP/1.1 or HTTP/2.0.
I understand this is not superagent specific but could be in the Node serverResponse object.
Thank you for the quick reponse. :+1:
Though the function is now there on .post() it still doesn't seem possible to stop redirect with .redirects(0). Is that intended?
EDIT: Sorry, I just realised it's probably not possible to stop redirects within the browser version.
Most helpful comment
Use
.on('redirect', callback)