Apache .htaccess query string redirects

January 15th, 2009 at 11:16 pm • permalink8 comments

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://mydomain.site/destination.php

If you need to mass-redirect a group of pages you would probably need to use the RedirectMatch directive.

RedirectMatch ^/oldfolder/(.*)$ http://mydomain.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, either 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.

Redirect /page.php?id=3  http://mydomain.site/page/3
Redirect /page.php?id=4  http://mydomain.site/page/4

RedirectMatch ^/page.php?id=([0-9]*)$  http://mydomain.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://mydomain.site/page/%1.pdf [R=302,L]

Let me explain the solution for those who wants to learn and not only to copy.

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. First 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 keyword.

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.

PS. If you suffer from “write-as-less-as-possible” sickness you might want to change the original rewrite statement with

RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^page\.php$ http://mydomain.site/page/%1.pdf [R=302,L]
  1. Apache RewriteRule and query string
  2. Logging external referers with Apache
  3. Apache Log Regex: a lightweight Ruby Apache log parser
  4. Generic Apache configuration snippets
  5. Redmine 0.9.0 and duplicate content issue

Filed in Server / Apache • Tags: , ,


Comments

[...] try to redirect a page depending on its query string. Our rewrite rule should looks like [...]

[...] Questa mattina mi ha citofonato Francesco, intento a risolvere proprio questa situazione. Tutto nasce dal problema che non è possibile utilizzare mod_alias per impostare un redirect basato su un parametro in querystring. Per approfondimenti vi rimando all’articolo Apache .htaccess query string redirects. [...]

Ellimist says:

Thanks!

I was having a hard time redirecting URLs based on query strings; and this article was very useful.

Sruthi says:

I have a problem in my htaccess because of query string…

my url is like

http://www.test.com/index.php?env=-buyers/profile_view:m1–1-2-s-&admin=1
http://www.test.com/index.php?env=-buyers/project_edit:m1–1-2-s-:projects—OnNew-&admin=1

if the url contains admin=1 the url should not be rewritten else it has to be rewritten. Can you please help in writing a condition for admin=1?

Thanks in advance,
Sruthi

You should use RewriteCond before RewriteRule and check agains the %{QUERY_STRING} environment variable.

Guido Mallee says:

Hm, somehow your last example results in a redirect to ‘http://www.mydomain.site/page/123.pdf?id=123′ instead ‘of http://www.mydomain.site/page/123.pdf

And how do i write the rule to redirect something like ‘page.php?id=123&name=abc’ ‘to page/123/abc’.

Thanks!

Just add a trailing ?.

RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^page\.php$ http://mydomain.site/page/%1.pdf? [R=302,L]

Here’s the answer to the other question.
http://www.simonecarletti.com/blog/2009/01/apache-rewriterule-and-query-string/

Guido Mallee says:

Thanks! Works perfect now!

Add a Comment




Follow Me
    Random Quote