Apache .htaccess query string redirects

January 15th, 2009 at 11:16 pm • permalink39 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]

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!

Neil says:

Just what I was after, thanks Simon!

Morningtime says:

What about this situation?:
http://www.domain.com/content/?c=123&x=123

It doesnt work, because the filename is missing. This would work:
http://www.domain.com/content/index.php?c=123&x=123

But this doesnt:
http://www.domain.com/content/?c=123&x=123

streamfinder says:

Thanks for this article – just what I was looking for. Spent an hour on google yesterday parsing terse apache posts and yours just worked. Thanks again

K says:

I must be lacking a few billion neurons because I can’t for the life of me understand this whole regex crap.

So I’m trying to catch all query strings containing “com_virtuemart” and redirect that request to the new store which is located at index.php?option=com_content&Itemid=154&id=92&lang=en&view=article.

Now, if I understand this correctly, I start with this:

[code]RewriteCond %{QUERY_STRING} ^.*(com_virtuemart).*$[/code]

I don’t know how to get this query match thing. That tells me that it’s starting the line at ^, then matches any characters except new lines – the ., then * is for 0 or more characters, and then () is a group of matches, in my case just 1 item com_virtuemart, after which again it’s matching any number of characters that are not newlines (pretty dumb since newlines do not exist in a URL but if I take that out I get a 500 error), and ends the line at $.

Cool! Now the second part.
[code]RewriteRule .*(virtuemart).*$ index.php?option=com_content&Itemid=154&id=92&lang=en&view=article[/code]

I don’t get why I have to match the request again, since the one above it did it, but so be it, anything containing virtuemart will be redirected to the right place.

Well, it doesn’t work. My RewriteRule is working if I comment out the QUERY_STRING, but of course it then only looks at physical locations, not at stuff coming after the ? in a url.

Thanks for any and all help.

RewriteCond %{QUERY_STRING} ^.*?com_virtuemart.*?$
RewriteRule ^(.*)$ index.php?option=com_content&Itemid=154&id=92&lang=en&view=article [R=301,L]

Hi,

Awesome post, was a great help! I set up a similar rule as ‘K’ above.

Only thing is that since I hard coded by ID, since I have two rules with similar IDs it forwards the page with the “361″ ID to the page for the ID “36″

RewriteCond %{QUERY_STRING} ^.*?products_id=36.*?$
RewriteRule ^(.*)$ http://www.domain.com/page-name1.html? [R=301,L]

RewriteCond %{QUERY_STRING} ^.*?products_id=361.*?$
RewriteRule ^(.*)$ http://www.domain.com/page-name2.html? [R=301,L]

skdeep says:

Thanks your code works perfect…. ive browse more than 50 tuts to find the solution….
fav
see u

chinaski says:

Thanks for this. I was trying to use Redirect and RedirectMatch to do the rewrite and was (naturally) having problems. A few googles and I found your article. Problem solved and some learning passed via the interwebs!

Rich says:

Thanks for the info. Still can’t quite get the right rewrite format though. I changed ecommerce engines and need to remove a query string in the middle and the end of the url

My old url: http://www.123safe.com/cgi-bin/SoftCart.exe/scstore/p-1031209AL.html

new url: http://www.123safe.com/scstore/p-1031209AL.html

some old links will have the shopping cart id attached after the .html. For example:

http://www.123safe.com/cgi-bin/SoftCart.exe/scstore/p-1031209AL.html?L+scstore+mzbz8040ff0bcd0b+1159202257

Thanks for all your help.

JeLBee says:

how to redirect this:

http://www.domain.com/title.html?source=2?add=2?sample=23 to
http://www.domain.com/title.html

need help… :)

what is the htaccess

Hello Jel Bee,

I wants to do same as you…

http://www.domain.com/category.html?p=1&limit=40 to http://www.domain.com/category.html

category.html will differ.. i can’t give static ‘category.html’ in RewriteRule.

RewriteCond %{QUERY_STRING} (.*)(^p=[1]&?|^&p=[1]&|&p=[1])$(&?.*)$
RewriteRule (.*) %{REQUEST_URI}?%1%3 [L,R=301]

i used above code to redirect when “p=1″.

Logan Smith says:

hi there,
i like to be able to redirect traffic coming in with specific search keywords (like those tracked with google analytics) to a specific page on another site. Can this be done from the .htaccess file on Apache webserver?
Need Help!!

Kostya says:

Hello
Thank you very much for your post!
I need to close access to specific url on my site like this : “index.php?act=add”
So is it possibe to create some rule in .htaccess file to close access to this url or make server respond error 404 instead of 200 ok ?
I have tried to this one but it is not working:

RewriteCond %{QUERY_STRING} act=add
RewriteRule ^/index.php – [F]

If someone knows how to do this comment please.

AZL says:

Hi

This is great help and I think I understand it! In your mass-redirect section you suggest:

RedirectMatch ^/oldfolder/(.*)$ http://mydomain.site/newfolder/$1

Does this assume a matching new page for each of the old pages? I am trying to redirect all pages to a single page with fixed content (regardless of the extension) so would the command look like this?

RedirectMatch ^/oldfolder/(.*)$ http://mydomain.site/newpage.html (new page is a fixed content and not dynamic).

Regards

AZL

worked.

RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{QUERY_STRING} ^q=foo$
RewriteRule ^(.*)$ /bar/results/? [R=302,L]

thanks.

Merlinox says:

To use more query_string parameter it needs to add on the end of {QUERY_STRING} definition the [OR] or the [AND].

Milap says:

Thanks for sharing,
Working nice !!!

Lee Marshall says:

Exactly the info and instructions I needed.

Thank you.

Craig says:

Thanks for the great article.

Trying to redirect links in from search engines which add very messy query strings to links.

http://www.mysite.com/holidaycottagesdetails.aspx?country=edinburgh-apartment2#utm_blahblahblahblahblahblah

I just want the redirection to have “edinburgh-apartment2″ on the end, nothing else. So far I have:

RewriteCond %{QUERY_STRING} ^country=([a-z|A-Z|0-9|-]*)$
RewriteRule ^(.*)/holidaycottagesdetails.aspx$ $1/holiday-rentals/%1? [NC,L,R=301]

But it fails. I was hoping the match would stop at the #utm bit. Any advice greatly appreciated:)

Craig

yoav says:

Very nice! this article answered all of my questions.

yoav says:

I have a problem though – after the redirection, it ads the parameter to the new url. so:
http://www.myweb.com/page.php?id=5
is being redirected to:
http://www.myweb.com/?id=5

using this rule:
RewriteCond %{REQUEST_URI} ^/page\.php$
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^(.*)$ “http://www.myweb.com/” [R=301,L]

PK says:

ok.. I’m getting the following requests and for the sake of god I can’t seem to resolve the problem.

The requests I’m getting are http://example.com/?/post-name
they need to be rewritten to http://example.com/post-name

I’ve been banging my head against the wall on this one for weeks.. any ideas / solutions anyone?

Been trying to do this in .htaccess but it’s just not working.

Laura says:

Thanks for this really useful post Simone!
I think I actually understand the baffling world of .htaccess redirects a *little* better now

Cheers
Laura

Rahul says:

when i was doing redirection usinh htacess, query string was getting appened, following rulwe worked for me:

RewriteCond %{REQUEST_URI} ^/article/starting-a-business/starting-up-how-to-s/article.php$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/article/resources/latest/\? [R=301,L]

note the back slash in the last of the rule

fabio says:

After had lose hours, I found this great useful post.
Thanks Simone.

EduSagar says:

Just what i wanted.. Thanks Simone.

D4ft says:

Hi there,
I am not familiar with apache,
how I can start with it?
how to find and edit the .htaccess file from my php enabled cpanel.
Your great reply apreciated,
thank you.

c0c0b33fs says:

w00t! Thanks much. Many tacos in your future.

Abhishek says:

Hello,

I used your code in the htaccess for a page to modify the url, It did but after redirection to that url, I am getting 404 error.

Here is the htaccess and url the I am modifying

Options FollowSymLinks
Options -MultiViews
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/profile\.php$
RewriteCond %{QUERY_STRING} ^user_id=([0-9]*)$
RewriteRule ^(.*)$ http://www.meenmipage.com/user/%1? [R=302,L,NC]

Actual Url was:-
http://www.meenmipage.com/profile.php?user_id=2
and modified was:-
http://www.meenmipage.com/user/2

Please tell me what to do?

Waiting for your reply…

Thanks
Abhishek Arora

Jason says:

Completed stumped your code works great when I make a non www request but when I have www in the url it goes to a 404 error, help would be very appreciated.

Thanks

Add a Comment




Follow Me
    Random Quote