39

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

Daniel Cook
  • 1,033
  • 1
  • 9
  • 19
  • Actually another solution, that would be better for me is to calculate the destination SEO URL for the form and action that. Extra query, but the URL would be preserved and a 301 redirect wouldn't be needed. – Daniel Cook Nov 29 '12 at 15:15

4 Answers4

76

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

Community
  • 1
  • 1
Hashbrown
  • 12,091
  • 8
  • 72
  • 95
34

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.

Ray
  • 40,256
  • 21
  • 101
  • 138
  • Thanks, I'm going to assume doing such a thing could make login forms display the username/password in the browser URL bar. I am steering myself towards updating each form to post to the calculated dynamic SEO URL. – Daniel Cook Nov 29 '12 at 15:27
  • 1
    @DanielCook You could also put the POST variables in a session if the redirect is to a same domain url and you don't want them in the URL. Just don't forget to force flush the session before issuing the redirect. I don't think GET parameters affect SEO of a URL however, it would just be visually ugly. – Ray Nov 29 '12 at 15:30
  • Thanks, maybe this will work. Apache sends all post requests to 'redirectPost.cfm', this stores form data in session.form and redirects the URL (losing post data). Once the 'redirect.cfm' picks it up it writes all session.form data back into the form scope before delivering the content. – Daniel Cook Nov 29 '12 at 15:37
  • Doh, just realised a redirect to 'redirectPost.cfm' would lose the post data. Perhaps another type of redirect, 307? keeps the post data, I will have to look that up. – Daniel Cook Nov 29 '12 at 15:44
  • @DanielCook you don't redirect to your redirect handler page, you just serve it up the do a single redirect on that page. No rediect 30x preserves post parameters – Ray Nov 29 '12 at 15:47
  • I had confused myself, I'm clear now. thanks, I will try it out. – Daniel Cook Nov 29 '12 at 15:53
  • @Ray I'm afraid you are mistaken, about the SEO thing. Any system will treat the full URL as unique. That includes also the url parameters (aka "query string"). So /index?1 and /index?2 are different urls. And they ARE different. That's the reason that google will treat them as actual different urls. – daniel.gindi Feb 03 '13 at 14:59
  • @daniel.gindi Thanks for noting the ambiguity. I think I wasn't clear in my comment. I didn't mean URLs with different get parameters are treated as the same resource for SEO purposes. I completely agree to your point `/index?1` != `index?2`. What I meant to convey was I didn't think similar URLs one using GET params vs. on not had any affect on SEO value. For example choosing between closely formed urls `/index?id=1` vs. just `/index` for a page I don't think either would have major SEO affect one way or the other. – Ray Aug 19 '14 at 14:38
  • @daniel.gindi Also, I'm not applying all URL stucture choices are SEO equal. For example `/index?id=19283b&post=2211` vs. `/articles/great-dallas-restaurants`, assuming the article is about great restaurants in dallas, MIGHT have better overall SEO impact using the second URL. – Ray Aug 19 '14 at 14:42
  • @Ray I'm afraid you are mistaken again, about the first point. Even if two urls are very similar, Google will kick you in the butt about having two urls with the similar content. You will have to declare them canonical. But about the second point is correct, A url with contextual info in the URL itself is better from an SEO point of view. – daniel.gindi Aug 19 '14 at 15:29
  • @daniel.gindi I think I need to be clearer. I'm not suggesting having two active urls to the same source--that has major SEO implications and you have to be careful and flag one canonical as you mention. The comments I made were only intended to address the factors to think about when you are choosing a single URL to use for a specific resource, when between picking one URL structure or the other, which would be better from an SEO standpoint or what would probably not affect SEO much at all. – Ray Aug 19 '14 at 16:00
  • @Ray Yes that is a different matter. I was addressing the different Urls that will be created by converting POST forms to GET – daniel.gindi Aug 19 '14 at 19:52
  • @daniel.gindi I think if the initial request being redirected is a POST, there shouldn't be any SEO impact. I think the only URLs listed or followed in search engines like google are those in anchor tags (that are all GET requests). No legit crawler should submit requests as POSTs to a form url, so no crawler should be redirected to the new final URL with appended get parameters, so search engines should never 'see' the URL with the parameters in them. I know people suspect google of submitting forms, but I've never come across a POST url in my searches. – Ray Aug 19 '14 at 20:01
  • @Ray What really happens is that your browser, say Chrome, is seeing those URLs because you have visited them. Chrome sends "anonymous statistics", which includes the URLs to crawl. We have observed this behaviour in the past and got used to putting a ROBOTS file in every site that is not in production yet, because Google got to know the URLs even before us... – daniel.gindi Aug 20 '14 at 04:59
  • @daniel.gindi interesting. I've heard of such statistics in chrome as well as anything google analytics may be sending back. Still, I'm not yet convinced these actually get indexed if the actual url is not crawlable but behind a 301 from a POST request. I'm definitely not an authority on this, so I will start keeping an eye out for these showing up in my webmaster tools as indexed pages. I don't think it's outside the realm of reason they could since all the data is going to the same source, google. – Ray Aug 20 '14 at 13:22
  • @Ray Well, from my (and friends') experience - they actually do it. As long as the URL exists, and you did use it (even if coming from a "form") - it is crawlable, and Google will find it. There IS a solution though, using either ROBOTS or adding CANONICAL tags to the pages. – daniel.gindi Aug 20 '14 at 16:53
  • @daniel.gindi I see your point. I agree CANONICAL (without the GET params) can ensure the final redirected URL to will limit SEO juice to only one permutation of the URL. If google is detecting using such urls, using canonical will protect you. If they're not, it doesn't hurt as it still clarifies things. Will update my answer to include this detail. Thanks! – Ray Aug 20 '14 at 17:02
  • @Ray well now I feel comfortable upvoting your answer, it's safe now ;-) – daniel.gindi Aug 20 '14 at 18:59
  • So no option to indicate a 307, or something else, which is permanent, to the browser to reissue a POST request to a different URL? – Nathan B Sep 29 '21 at 15:04
  • @NathanB This answer (and question) is quite old. Looks like modern browsers now support the 307 properly as noted in Hashbrown's answer. Will update. – Ray Oct 01 '21 at 18:17
  • I think there still is a problem in some browsers. Firefox for example. For some browsers sending 307 resulted the browser convert to GET request, which obviously created critical problem for some users. – Nathan B Oct 02 '21 at 19:05
  • MDN indicates that current firefox should respect the method and body redirect: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307 , but I've not personally tested. – Ray Oct 04 '21 at 16:29
0

Strictly, the correct code to use is 308, corresponding to the permanent redirect nature of 301, and preserving request method:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308

The support for code 308 across browsers is acceptable.

enter image description here

datasn.io
  • 12,564
  • 28
  • 113
  • 154
-1

Using 301 redirects for general URL rewriting is not the way to go. This is a performance issue (especially for mobile, but also in general), since it doubles the number of requests for your page.

Think about using a URL rewriting tool like Tuckey's URLrewriteFilter or apache mod_rewrite.

What Ray said is all true, this is just an additional comment on your general approach.

marc82ch
  • 1,004
  • 3
  • 11
  • 27
  • I've had a look at the above, trying to get an idea for what's possible. An example suggestions Standard URL: http://www.example.com/list.cfm?product=fruit&page=1&order=asc&perpage=30 Rewrite URL: http://www.example.com/list/fruit/asc/30/1 However my URLs will be domain.com/folder1/folder2/folder3/index.cfm?id=12345 and resolve to domain.com/area/id-title-of-the-article/ The information is not available in the DB and will require some DB queries to ascertain title and area. – Daniel Cook Mar 31 '14 at 08:18
  • Hi. I would really appreciate your response. I have a page that redirects: https://bvop.org/project-management-certification/ Unfortunately when it redirects the new URL looks like this: https://bvop.org/projectmanagement/?project-management-certification/ It contains the original URI after a weird ? character for a query parameter. I need to remove these but I cannot. Do you have any idea? – Liam James Feb 06 '20 at 13:36