Apache 301 Redirect and preserving post data

I have implemented SEO URLs using Apache 301 redirects to a 'redirect.cfm' in the root of the website which handles all URL building and content delivering.

Post data is lost during a 301 redirect.

Unable to find a solution so far, have tried excluding post method from rewrites - worst case scenario we could use the old type URLs for post methods.

Is there something that can be done?

Thanks


Solution 1:

Using a 307 should be exactly what you want

307 Temporary Redirect (since HTTP/1.1)
In this case, the request should be repeated with another URI; however, future requests
should still use the original URI.[2] In contrast to how 302 was historically implemented,
the request method is not allowed to be changed when reissuing the original request. For
instance, a POST request should be repeated using another POST request

- Wikipedia

Solution 2:

Update circa 2021 The original answer here was written before 307 status code redirect worked consistently across browsers. As per Hashbrown's answer below, the 307 status code should be used.

Old Answer POST data is discarded on redirect as a client will perform a GET request to the URL specified by the 301. Period.

The only option is to convert the POST parameters to GET parameters and tack them onto the end of the URL you're redirecting to. This cannot be done in a .htaccess file rewrite.

One option is to catch POST requests to the url to be redirected and pass it off to a page to handle the redirect. You'd need to do the transposition of the parameters in code then issue the redirect header with the parameter appended new url that way.

Update: As pointed out in the comments to this answer, if you do redirect to another URL specifying POST parameters and that URL is also accessed without paramters (or the params are variable), you should specify a link to the canonical URL for the page.

Say the POST form redirects transposed to the following GET resource:

   http://www.example.com/finalpage.php?form_data_1=123&form_data_2=666

You would add this link record to the head section of the page:

   <link rel="canonical" href="http://www.example.com/finalpage.php" />

This would ensure all SEO value would be given to http://www.example.com/finalpage.php and avoid possible issues with duplicate content.