One of the most common question when talking about Apache and mass-redirections, is how to configure a query string based redirect for a specific page. Creating a single page redirect in Apache is as simple as writing the following line in your .htaccess
file:
Redirect /page.php http://example.site/destination.php
If you want to mass-redirect a group of pages you will probably need to use the RedirectMatch
directive:
RedirectMatch ^/oldfolder/(.*)$ http://example.site/newfolder/$1
This will redirect any page from the oldfolder
to the corresponding one in newfolder
with a convenient one-by-one redirect.
Unfortunately, neither Redirect
nor RedirectMatch
allow you to specify a query string for the redirect source. It other words, the following statements are invalid and they will simply be ignored:
# You can't Redirect with a query string
Redirect /page.php?id=3 http://example.site/page/3
Redirect /page.php?id=4 http://example.site/page/4
# You can't RedirectMatch with a query string
RedirectMatch ^/page.php?id=([0-9]*)$ http://example.site/page/$1
The solution requires to change the focus from mod_alias
to mod_rewrite
. Here's an example:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/page\.php$
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^(.*)$ http://example.site/page/%1.pdf [R=302,L]
Explanation
The first line enables the RewriteEngine
module. Please note that mod_rewrite
Apache module must be installed and enabled in order to use the RewriteEngine
.
The RewriteCond
statements set all the rewrite conditions. The forth line, the real rewrite directive, will be executed if and only if all conditions are satisfied by the current request.
First I want to check the request is for the page I need to redirect. Skipping this condition might cause some unexpected behavior if other pages in my website are using the id
parameter. Then I want to base the rewrite rule on the value for the current request query string. Be sure to wrap the id
value within a regular expression match to be able to reuse the match later as a back-reference.
Finally I can write my redirection rule. This line looks like a RedirectMatch
statement: I specify the pattern for the redirection source, then the redirection target. As you can see, the value for the id
parameter captured by the last RewriteCond
is referenced in the target with the %N
token where N
is the number of the match in the regular expression.
The comma separated values at the end of the RewriteRule
line define which flags should be applied for this rule. I want to setup a 302 Redirection and be sure Apache won't execute any other rule after this one.
In this simple example, you can also squeeze the the original rewrite statement into 3 lines:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^page\.php$ http://mydomain.site/page/%1.pdf [R=302,L]