Small "hic" with a 301 htaccess redirect - .htaccess

i would like simply to create a 301 redirect, but my code does'nt work and returns a beautiful 404 page (-_-).
I think the problem is the "?" in the from url, i tried to escape it but it doesn't work anymore.
RewriteRule ^produit.php?PDT_ID=473 /product.php?id_product=210 [R=301]
Thanks to take a look

It's a common mistake. As the docs say, to test for things in the query string, you need to use a RewriteCond directive, like this:
RewriteCond %{QUERY_STRING} PDT_ID=473
RewriteRule ^produit.php /product.php?id_product=210 [R=301]
Which means "if the query string matches the pattern 'PDT_ID=473', and the pattern matches the uri, then rewrite". Note that you might want to make the rewriteCond's regex more foolproof to ensure it won't match things like APDT_ID=4735 as well, but this should get you started.

Related

URL rewrite more precise match, not URLs that just start with the same string

Let's say I have phpbb3 forums software and I want to prettify some URLs. I put this in my htaccess:
RewriteRule ^cake viewforum.php?f=5&%{QUERY_STRING} [L]
which works for domain.tld/cake and domain.tld/cake/ but it also catches domain.tld/cake-recipes and domain.tld/cake-recipes/ for instance, and so rewrites them.
How can I write this so that it only matches that exact URL, not URLs that begin with that string?
You need to add $ in order to delimit your rule pattern.
RewriteRule ^cake/?$ viewforum.php?f=5 [L,QSA]
The above rule will now only match domain.tld/cake or domain.tld/cake/.
Also, you can avoid using %{QUERY_STRING} by adding QSA flag (which does the same, but in a more elegant way)

URL Rewriting not possible?

I have a website with this url :
http://www.example.com/stage?dept=01
I want transform this url to this
http://www.example.com/stage-ain.html
I want that new url override the standard html and it's become the only url available (for SEO).
I do this, but it's not ok :
RewriteEngine On
RewriteRule ^stage?dept=01$ stages-ain.html [R=301]
Have you an idea ?
Thanks
The first argument of RewriteRule cannot match the query string. You have written a regex instead that matches the url stagedept=01 and stagdept=01.
You want to use a RewriteCond instead. You could use the %{QUERY_STRING} variable, but this will likely cause an infinite loop. Instead you probably want to match on %{THE_REQUEST}.
RewriteCond %{THE_REQUEST} /stage\?dept=01
RewriteRule ^ stages-ain.html [R,L,QSD]
Change the [R] flag to [R=301] when you have tested everything works as expected. Always use the L flag with external redirects, unless you have a very good reason to continue rewriting, as this can cause some weird problems.
See the documentation for more information.

Redirecting a URL that contains a question mark

It's been necessary to move the position of my blog and I'm trying to make sure I catch all of the links in via the old link and redirect them to the new one.
The blog has been moved from http://example.com/ to http://example.com/blog/
The URLs used to generate with the date before the post name (by default) which I've decided not to do, to keep the URLs memorable.
The issue is that there's a ? character in the original URL (the default URL produced by the CMS I'm using and it's causing problems with the redirect:
RewriteRule ^post.php?s=2012-01-01-blog-post$ /blog/blog-post? [R=301,L]
So I need to escape the ? somehow but I can't work out how!
I could use a more general redirect that avoids the ? but that would redirect to the listings page, not the article itself:
RewriteRule ^post.php$ http://tempertemper.net/blog/? [R=301,L]
How do I make it read the ? as part of the URL!?
Thanks for taking a look!
Martin :)
I think you need to use a RewriteCond to check for the presence of a QUERY_STRING value and then, assuming the query string matches your blog pattern, capture the blog name and then use the captured value in the RewriteRule. Something like this:
RewriteCond ${QUERY_STRING} ^s=[0-9]{4}-[0-9]{2}-[0-9]{2}-(.*)$
RewriteRule ^post.php$ /blog/%1 [R=permanent,L]
The %1 refers to the first capture pattern in the matching RewriteCond (and the RewriteRule will not trigger unless the RewriteCond is a match).
The reason this is necessary is that a RewriteRule cannot see the query string as part of the request path, so you have to check for (and capture) a query string using a RewriteCond before the RewriteRule.

301 redirect from URL with query string to new domain with different query string

I am trying to figure out how to do a 301 redirect in my htaccess file to redirect some files to a new domain. Here's what I need to know how to do:
OLD URL: http://www.example.com/index.php?page=news&id=2366
NEW URL: http://www.example2.com/news.php?name=23546
The redirects don't have to be automatically created. I can hard-code the pages I need to redirect in the htaccess file, I just don't know the format to use as I've read that a "standard" 301 redirect won't work with query strings.
Basically this is what I want to do, but from my research so far it doesn't sound like it can be done this way.
redirect 301 /index.php?page=news&id=2366 http://www.example2.com/news.php?name=23546
You could use a rewrite rule with a query string match condition, such as:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/index.php$
RewriteCond %{QUERY_STRING} ^page=news&id=2366$
RewriteRule ^(.*)$ http://www.example2.com/news.php?name=23546 [R=301,L]
Checkout this blog page for more information on how this works.
I had the same problem, but still more complicated, because I needed to discard other parameters.
Like this: my-old-page.php?a=1&b=2&c=3
I need to use one of the strings and discard the others, but that solution only worked if I want to use the last parameter (c=3). If I want to use any other (a=1 or b=2) it runs to a 404. After much struggling and searching, I found an answer:
RewriteCond %{QUERY_STRING} ^.* ?b=2.* ?$ (without space after the *)
RewriteRule (.*) http://www.my-webpage.php/new-location-2? [R=301,L]
The solution is to add ".*?" before and after the parameter to use.
I don't know if this is the best solution, but it works.

301 Redirecting URLs based on GET variables in .htaccess

I have a few messy old URLs like...
http://www.example.com/bunch.of/unneeded/crap?opendocument&part=1
http://www.example.com/bunch.of/unneeded/crap?opendocument&part=2
...that I want to redirect to the newer, cleaner form...
http://www.example.com/page.php/welcome
http://www.example.com/page.php/prices
I understand I can redirect one page to another with a simple redirect i.e.
Redirect 301 /bunch.of/unneeded/crap http://www.example.com/page.php
But the source page doesn't change, only it's GET vars. I can't figure out how to base the redirect on the value of these GET variables. Can anybody help pls!? I'm fairly handy with the old regexes so I can have a pop at using mod-rewrite if I have to but I'm not clear on the syntax for rewriting GET vars and I'd prefer to avoid the performance hit and use the cleaner Redirect directive. Is there a way? and if not can anyone clue me in as to the right mod-rewrite syntax pls?
Cheers,
Roger.
As the parameters in the URL query may have an arbitrary order, you need to use a either one RewriteCond directive for every parameter to check or for every possible permutiation.
Here’s an example with a RewriteCond directive for each parameter:
RewriteCond %{QUERY_STRING} ^([^&]&)*opendocument(&|$)
RewriteCond %{QUERY_STRING} ^([^&]&)*part=1(&|$)
RewriteRule ^bunch\.of/unneeded/crap$ /page.php/welcome? [L,R=301]
RewriteCond %{QUERY_STRING} ^([^&]&)*opendocument(&|$)
RewriteCond %{QUERY_STRING} ^([^&]&)*part=2(&|$)
RewriteRule ^bunch\.of/unneeded/crap$ /page.php/prices? [L,R=301]
But as you can see, this may get a mess.
So a better approach might be to use a RewriteMap. The easiest would be a plain text file with key and value pairs:
1 welcome
2 prices
To define your map, write the following directive in your server or virual host configuration (this directive is not allowed in per-directory context):
RewriteMap examplemap txt:/path/to/file/map.txt
Then you would just need one rule:
RewriteCond %{QUERY_STRING} ^([^&]&)*opendocument(&|$)
RewriteCond %{QUERY_STRING} ^([^&]&)*part=([0-9]+)(&|$)
RewriteRule ^bunch\.of/unneeded/crap$ /page.php/%{examplemap:%2}? [L,R=301]
RewriteCond %{QUERY_STRING} option=com_content&task=view&id=70&Itemid=82
RewriteRule ^index.php http://www.example.com/business/banks/? [R=301,L]
The ? will prevent the url the user is sent to from having the same query string as the origin page.
In summary, you could use RedirectMatch with a regex that will match the full URL, including query string. That will let you rearrange parts of the URL, but if you have to do conversions like "opendocument&part=1" to "welcome" (where the new URL is completely different from the original one), you might need a RewriteMap - or perhaps better, just send all URLs to page.php and parse the query string in PHP.
EDIT: If it's just a few URLs you want to redirect, you could probably write out individual rules like
RedirectPermanent http://www.example.com/bunch.of/unneeded/crap?opendocument&part=1 http://www.example.com/page.php/welcome
RedirectPermanent http://www.example.com/bunch.of/unneeded/crap?opendocument&part=2 http://www.example.com/page.php/prices

Resources