Koa: Redirect 302/303

Created on 19 Jan 2015  Â·  15Comments  Â·  Source: koajs/koa

I know it's not profoundly important, but wouldn't it be better for the default redirect status to be 303 rather than 302?

Qv http://stackoverflow.com/questions/4764297, http://stackoverflow.com/questions/5129076.

Most helpful comment

Would you accept a PR that allows an optional parameter to ctx.redirect for setting the status code?
And maybe a ctx.redirect.status variable to save the default?

Never mind. One can always do

ctx.redirect("/")
ctx.status = 303

No need to bloat the API surface.

All 15 comments

i wouldnt mind. is there some sort of consensus on this? anyone else care?

Note: Many pre-HTTP/1.1 user agents do not understand the 303 status. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303.

Sounds about right to me, I've never seen the opposite behaviour but we're probably well beyond being safe to move to 303 as well, so I guess it doesn't really matter (unless someone can find a real case)

That note is from RFC 2616 (§10.3.4), from 1999. See also RFC2616 is Dead, RFC 7231. I know, I’m just a pedant, but if there’s a time to do it right, it’s when Koa is young.

yikes ok that's old, SGTM!

These days, don't refer to RFC 2616; RFC 7230 to 7235 are the main replacement RFCs :)

From RFC7231, it looks like 307 should be used instead of 302, not 303. I think that the latter should be reserved for situations where one wants to explicitly reference a new location for a new resource:

If the result of processing a POST would be equivalent to a
representation of an existing resource, an origin server MAY redirect
the user agent to that resource by sending a 303 (See Other) response
with the existing resource's identifier in the Location field.

@ruimarinho - not as I read the spec:

[303 (See Other)] is primarily used to allow the output of a POST action
to redirect the user agent to a selected resource, since doing so provides
the information corresponding to the POST response in a form that can
be separately identified, bookmarked, and cached, independent of the
original request.

whereas

The 307 (Temporary Redirect) status code indicates that the target
resource resides temporarily under a different URI and the user agent
MUST NOT change the request method if it performs an automatic
redirection to that URI.

I think 307 is primarily for when you want to re-post the same post data to a different URI; whereas that guidance in §4.3.3 is saying that it is acceptable to use 303 to redirect from a POST request to the same resource again (as a GET) – that is, to stay on the same page after a POST.

Right, I agree with your interpretation. What I was referring to, though, is to what koa users generally have in mind when redirecting users to another location - right now, by choosing a 302 as the default, we are basically optimising for a 303-like redirect. This works well when, for instance, you send a POST to create a resource and then redirect the user to the resource's new location via a 303. However, in these scenarios, you could opt for a 201 with the Location header pointed to the new resource instead.

Now, if we're simply optimising for a route redirect - no semantics involved, then that would be a 307 if we just want to relay the request to another endpoint (a POST continues to be a POST, no conversion happens on the user agent).

I'd say going for a 303 is more biased towards the "redirect after POST behaviour" but at the same time it's what 302 has become these days, so there's less chance for this to be become a breaking change, even if technically a 302 should have been interpreted as a 307 since the beginning 👀

@ruimarinho, I get you now. I agree, the ‘correct’ replacement for a 302 should be a 307, except that the 302 was so universally misinterpreted that that would create breaking behaviour.

201 would be appropriate following a POST if the redirected page is a representation of the resource, but not if it was, for instance, a list of such resources (after adding a widget, transfer back to list of widgets); but I take it you are not proposing that as a default...

I think 303 would be the best default, as a) in my experience, ‘redirect after post’ is the commonest use case for redirect (accepting that other people’s running may vary), and b) it would be less of a breaking change as a replacement for 302.

Note: Koa documentation would have to be changed to match.

do we have a consensus?

@jonathanong possibly. Me and @chrisveness agree that changing the default to 307 would be a BC because nowadays people expect a 302 to behave like a 303 due to how user agents mishandled the spec. Docs, however, should be updated to recommend the usage of 307 in situations where the method and the data should be kept intact. I can submit a patch if a consensus is reached.

tidbit: looks like Django and RoR still go with 302 from what I can see, unless I'm looking at outdated docs haha. I think 303 for default

Did some research and Symfony2, Laravel and Spring also go with 302. Spring appears to have a flag that disables HTTP 1.0 compatibility, which in turns makes the default redirect status code a 303.

http://bloggingmax.net/303-redirect-and-its-effect-on-seo/ from 2015 and the side effects on search engines! Very, very important for one web framework.

it should stay 302 by default @tj @travisjeffery , but add option/setting to change it to whatever the user need.

Would you accept a PR that allows an optional parameter to ctx.redirect for setting the status code?
And maybe a ctx.redirect.status variable to save the default?

Never mind. One can always do

ctx.redirect("/")
ctx.status = 303

No need to bloat the API surface.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tracker1 picture tracker1  Â·  3Comments

ilkkao picture ilkkao  Â·  4Comments

dounine picture dounine  Â·  4Comments

xinshouke picture xinshouke  Â·  4Comments

koalex picture koalex  Â·  3Comments