4

For reasons that aren't worth going into here, Google have been indexing one of my sites with an unnecessary query string in the URL. I'd like to modify my htaccess file to 301 redirect all those requests to the URL without the unneeded part of the query string, but retain any other parts of the query string which may (or may not) be part of the address to make sure other functionality is retained.

For example, the following URLs

http://example.com/product.php?query=12345
http://example.com/index.php?section=ABC123&query=56789
http://example.com/search.php?query=987654&term=keyword

Would become

http://example.com/product.php
http://example.com/index.php?section=ABC123
http://example.com/search.php?term=keyword

Effectively stripping 'query=XXXXX' plus the ? or &, but making sure other queries are retained and in correct syntax after the removal (i.e., just removing ?query=98765 from the third example wouldn't work, as it would leave the link as search.php&term=keyword rather than search.php?term=keyword).

Was looking through some other Stack answers and found this:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING}  (.*)?&?query=[^&]+&?(.*)?  [NC]
RewriteCond %{REQUEST_URI} /(.*)
RewriteRule .*  %3?%1%2? [R=301,L]

But that doesn't seem to work, and my knowledge of htaccess & regex isn't good enough to figure out why.

Thanks in advance for any pointers.

2 Answers 2

8

Try this (i tested it with your examples and it is working fine):

RewriteEngine on

RewriteCond %{QUERY_STRING} ^(.*)&?query=[^&]+&?(.*)$ [NC]
RewriteRule ^/?(.*)$ /$1?%1%2 [R=301,L,NE]

Also, you should add a condition to apply this rule only on existing files (that's up to you).
If you want it:

RewriteEngine on
    
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{QUERY_STRING} ^(.*)&?query=[^&]+&?(.*)$ [NC]
RewriteRule ^/?(.*)$ /$1?%1%2 [R=301,L,NE]
Sign up to request clarification or add additional context in comments.

2 Comments

You may need the NE (noescape) flag on the RewriteRule directive in order to prevent the preserved parts of the query string being doubly URL-encoded (%-encoded) in the redirect response. This depends on the expected values in the query string. The QUERY_STRING server variable is not %-decoded, so the captured backreferences (%1 and %2) are already %-encoded. Normal behaviour of the RewriteRule directive is to URL-encode the response, but if it's already URL-encoded it will encode it again, corrupting the query string.
@MrWhite Nice catch, thanks !
3

It seems there is a mistake or something. Here is working solution:

RewriteEngine on

RewriteCond %{QUERY_STRING} ^(.*)&?query=[^&]+&?(.*)$ [NC]
RewriteRule ^(.*)$ /$1?%1%2 [R=301,L,NE]

This code removes just one parameter. Working perfect.

2 Comments

Works like charm for me. And if i want to remove more than one parameter? Just put same code line like this? *RewriteCond %{QUERY_STRING} ^(.)&?query2=[^&]+&?(.*)$ [NC] **
@MichelXavier You don't need to add another condition, just modify the existing CondPattern (regex) using alternation. eg. ^(.*)&?(?:query1|query2)=[^&]+&?(.*)$ - careful to make the alternation group non-capturing. Note that this will result in two redirects if both URL parameters should occur on the same request.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.