Sonny
Sonny

Reputation: 8326

One URL: Two Different Redirects

I have a URL that once handled GET and POST requests. I want it to now only handle POST requests, and do a redirect for other requests. Based on this question, it appears that I should use a 303 after processing a POST request, and a 301 for other requests.

My code flow would look like this:

if ('POST' === filter_input(INPUT_SERVER, 'REQUEST_METHOD')) {
    // process post request

    // set http status code
    header('HTTP/1.1 303 See Other');
} else {
    // set http status code
    header('HTTP/1.1 301 Moved Permanently');
}
header('Location: /newurl.php');

Is this the proper user of the redirect codes? I want to make sure the 301 won't be cached by browsers when a POST request is made.

Upvotes: 0

Views: 302

Answers (2)

Alexandru Guzinschi
Alexandru Guzinschi

Reputation: 5726

On 303 redirect you must specify a redirect URI:

<?php
header('HTTP/1.1 303 See Other');
header('location: http://www.example.com/some-url/');

As a workaround for caching the 301 response, you can set the expiration date in the past. This way the client is encouraged to mark the response as expired immediately:

<?php
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 1 Feb 1997 06:00:00 GMT');

The 303 response should not be cached by any client that respects RFC 2616:

The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable.

Considering the above, you could change initial code snippet to something like this:

if ('POST' === filter_input(INPUT_SERVER, 'REQUEST_METHOD')) {
    // process post request

    // set http status code
    header('HTTP/1.1 303 See Other');
    header('Location: http://www.example.com/newurl.php'); // FULL URI HERE
    exit;
}

// set http status code
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://www.example.com/other-page.php');

However, in your case a 307 redirect should be more appropriate. Although 307 is a temporary redirect and you will always redirect on any request that is not POST you can change this behavior in the future because as per RFC "Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI for future requests". The second advantage is that: "This response is only cacheable if indicated by a Cache-Control or Expires header field."

The requested resource resides temporarily under a different URI.
Since the redirection MAY be altered on occasion, the client SHOULD
continue to use the Request-URI for future requests. This response
is only cacheable if indicated by a Cache-Control or Expires header
field.

See RFC 2616 sec. 10.3.8

Upvotes: 1

MarcinWolny
MarcinWolny

Reputation: 1645

Your redirect should be

header('Location: http://www.example.com/newurl.php',true,301);

for 301 code, similar with 303 (so you don't need the last Location header). See the manual on header.

Upvotes: 1

Related Questions