10

I have two separated vhost. On the www. one, I have instaled this only line on .htaccess

redirectMatch 301 ^(.*)$ http://d_blur_blur_s.com$1

All works as expected except that in the case where the POST is converted to GET.
Please notice that the post has parametres as a get (i didn't do it, and I won't change it) i am just trying to avoid duplicated content. I am showing firebug trace.

I expect to have the POST redirected on the main domain with redirectmatch or other trick.

firebug trace

Update
I have half of the internal links on the site written with www and the other half without it. So I need to keep both public but not duplicated. I need the GETs forwarded as GETs and the POSTs frowarded as POSTs. the problem is big, I have 12000 pages indexed, and lot of forms. So I am first searching for a generic solution without changing code. I full control de server.

Thanks a lot

Saic Siquot
  • 6,513
  • 5
  • 34
  • 56

6 Answers6

7

A redirect response from your server for whatever request you made, regardless of it being POST or GET request, always results in your client making a GET request (unless you somehow enable it to NOT automatically follow redirects--sometimes I do this with curl, but I don't know any widely used browsers with this functionality available easily to the user). The client browser takes the URL provided by the redirect and treats it as a URL to perform a GET request. No way around it, the POST data is discarded by the server since it was intended for the server resource at the original URL.

If you redirect outside of .htaccess, say in a PHP file to construct redirect response, your only option is to convert the POST parameters into a string of GET parameters and add it to the end of the URL you send back to the client with your redirect response.

I'm fairly confident there is not a way to do automatic POST parameter appending to redirect in the .htaccess file or in the httpd.conf files whether you use the redirect directive or the rewrite directive via the mod_rewrite module.

Ray
  • 40,256
  • 21
  • 101
  • 138
7

You redirect using 307 instead of 301 to keep the post data, but some browsers show a dialog to the user if he is sure he want to sent the post data, so not real pretty.

But I'd rather go and fix the problem at the root. The only way you would get a post to the wrong domain is if the html-form refers to the wrong domain (e.g. <form action="www.d_blur_blur_s/public/main/loginGenerator.php" ...). Just fix the html.

Don't worry about duplicated content as search engines never send post-requests, only get. You current solution should do the trick to prevent duplicated content.

user987339
  • 10,519
  • 8
  • 40
  • 45
Gerben
  • 16,747
  • 6
  • 37
  • 56
  • this is correct but, I do not want to touch three party application by now – Saic Siquot May 18 '12 at 15:26
  • Superb! I was quite worried about my webhook processor service being able to use wildcard subdomain prefixes until I saw this. Thanks a million! – SteveCinq Jun 24 '20 at 23:03
  • So if doing R=307 instead of R=301 in the Apache RewriteRule the POST request will not be converted to GET request? – Nathan B Jun 24 '21 at 13:59
  • @NathanB Yes. That's what I said. From the [MDN website](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307): `The only difference between 307 and 302 is that 307 guarantees that the method and the body will not be changed when the redirected request is made.` – Gerben Jun 24 '21 at 15:03
5

The only way to do a redirect and preserve POST data (that I am aware of) is to use mod_rewrite with mod_proxy and then use P flag in RewriteRule.

On your www host enable mod_rewrite, mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

RewriteRule ^ http://d_blur_blur_s.com%{REQUEST_URI} [P]
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • I do not want to use mod_rewrite, becouse it will "generate" duplicated content – Saic Siquot May 18 '12 at 15:24
  • 1
    Duplicate content? All over the world in Apache installations mod_rewrite is used precisely for that reason i.e. to avoid duplicate content. – anubhava May 18 '12 at 15:27
  • the configuration that you propouse, responds with content on both the plain domain and the www subdomain, on both responds with the same content, so that is duplicated content – Saic Siquot May 18 '12 at 15:35
  • When you use Proxy the target URL i.e. `http://d_blur_blur_s.com/something` will never be exposed to your browser OR search engines and hence will not result in any duplicate content. Browser or search engines will only now of your original `www` URL. – anubhava May 18 '12 at 15:39
  • So you mean to say you already have duplicate content out there e.g.: `http://d_blur_blur_s.com/something` and `http://www.d_blur_blur_s.com/something` are both public URLs at present? – anubhava May 18 '12 at 16:09
  • yes, that is the case. Now I want one with content and the other redirected. – Saic Siquot May 18 '12 at 16:14
  • 1
    Sorry to come back late to this thread. What you need isn't entirely possible with .htaccess only. I believe you would be using some kind of web framework like Wordpress, Joomla etc that gives a feature of common footer function for all your pages. You can use my above code in .htaccess first to get POST data into desired domain and do all your processing there. Later in your footer you can do a conditional `301 redirect` through your code (like header function in PHP) to remove duplicates from search engines. However this requires little bit of coding something which you're trying to avoid. – anubhava May 21 '12 at 05:59
  • Can you explain what is the 'P' flag? – Nathan B Jun 24 '21 at 13:56
  • I have written in answer also. It is used for proxying requests. – anubhava Jun 24 '21 at 14:03
2

I bumped into this POST->GET rewrite as well. An API call like this:

  curl -X POST https://example.com/api/user/123456789

was entering my API framework with a GET request method.

The cause seems to be related to POST requests with an empty body. To avoid this issue you can set the Content-Length header:

  curl -X POST https://example.com/api/user/123456789 -H 'Content-Length: 0'

or pass something in the body:

  curl -X POST https://example.com/api/user/123456789 -d ''
Alex Pop
  • 168
  • 1
  • 6
1

In HTTP 1.1, statusCode (307) indicates that the request should be repeated using the same method and post data. Change the redirect type to fix it. enter image description here

Naruto
  • 653
  • 8
  • 19
0

Adding www to the base URL did it for me.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 13 '21 at 13:23