Redirection is not working with mod_rewrite in htaccess - apache

I need to redirect few URIs having query string like:
/pages/foo.bar?pageId=123456 to http://some.site/spam/egg/
/pages/foo.bar?pageId=45678 to http://another.site/spaming/egging/
I have this in my htaccess:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=123456$
RewriteRule ^.*$ http://some.site/spam/egg/ [R=301,L]
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=45678$
RewriteRule ^.*$ http://another.site/spaming/egging/ [R=301,L]
But its not working, showing 404. What am i doing wrong?

You need to move these 2 rules i.e. before all other rules just below RewriteEngine On line as other rules might be overriding this.
(Based on your comments) Your culprit rule is this rule:
RewriteRule . index.php [L]
Which is actually rewriting every request to index.php and changing value of REQUEST_URI variable to /index.php thus causing this condition to fail:
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$

From your example, you get redirected to
http://some.site/spam/egg/?pageId=123456
http://another.site/spaming/egging/?pageId=45678
You can use your browser developer tools to see the redirection (in the Network tab).
Maybe the query strings in the redirected URL lead to a 404? You can add a ? at the end of your redirection to clear the query string:
RewriteCond %{REQUEST_URI} ^/pages/foo.bar$
RewriteCond %{QUERY_STRING} ^pageId=45678$
RewriteRule ^.*$ http://another.site/spaming/egging/? [R=301,L]

Related

How can I set the RewriteCond for the exact URL only?

I need to make a hidden redirect from sitename.dom to sitename.dom2 keeping the rest of string untouched.
For now I use:
RewriteCond %{HTTP_HOST} ^sitename.dom
RewriteRule ^(.*) http://sitename.dom2/$1 [P]
and it works perfectly. But. Due to multilanguage on my website the frontpage has the following path:
sitename.dom2/lang
thats why when user calls sitename.dom he is being redirected (hidden) to sitename.dom2/ and he's getting 404 page.
So, please advise how do I make a strict redirect for exact request only sitename.dom without any further?
I had tried
RewriteCond %{HTTP_HOST} ^sitename\.dom$
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*) http://sitename.dom2\/lang [P]
with no luck.
BTW, inside the website language subpath doesn't affect at all. sitename.dom/lang/page works as good as sitename.dom/page
I had to add the single redirect before all other. And use dom2 instead of dom1 in this rule.
Here is the solution:
RewriteEngine On
#redirect front page only:
RewriteCond %{HTTP_HOST} ^sitename\.dom2$ [OR]
RewriteCond %{HTTP_HOST} ^www\.sitename\.dom2$
RewriteRule ^/?$ "http\:\/\/sitename\.dom2/\lang" [L]
#redirect all other pages:
RewriteCond %{HTTP_HOST} ^sitename\.dom2
RewriteRule ^(.*) http://sitename\.dom1\/$1 [P]
Simply add /lang in your first RewriteRule directive:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^sitename.dom$
RewriteRule ^ http://sitename.dom2/lang%{REQUEST_URI} [P]

Apache redirect using RewriteEngine with and without query string

I'm trying to get 2 redirections set on my htaccess file but I can't make it to work.
The desired output is:
if the user goes to www.mywebsite.com/page1, it gets redirected to /folder/newPage
if the user goes to www.mywebsite.com/page1?a=123, it gets redirected to /folder/anotherPage?a=123
I tried this
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/page1$ /folder/newPage [R=301,L]
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^/page1(.*)$ /folder/anotherPage$1 [R=301,L]
I also tried something like this:
RewriteCond %{REQUEST_URI} ^/page1$
RewriteRule ^(.*)$ /folder/newPage [R=301,L]
RewriteCond %{REQUEST_URI} ^/page1$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ /folder/anotherPage%1 [R=301,L]
Note that Rewrite mod is turned on on my apache.
Any idea how to make it work?
Check through the following:
RewriteEngine On is present before all the rules
AllowOverride directive allows your htaccess files to load
htaccess receives URLs without the leading slashes, unlike server config files, or VHosts file.
.* matches 0 or more characters, thus %{QUERY_STRING} ^(.*)$ also matches empty query strings. Change this to .+.
Final rules should be:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^page1$ /folder/newPage [R=301,L]
RewriteCond %{QUERY_STRING} ^(.+)$
RewriteRule ^page1$ /folder/anotherPage?%1 [R=301,L]

Apache RewriteRule fails on question mark

We had a typo when creating URLs, so
/wasserh?hne/wasserhahn-1-2-zoll-dg11040-e+1281
should be redirected to
/wasserhaehne/wasserhahn-1-2-zoll-dg11040-e+1281
the .htaccess starts with
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.kull-design.com$1 [R,L=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) index.php [L]
RewriteRule ^eng/deu index.php
and normally sth like this works
Redirect 301 /blog/tag/wasserhaehne-aus-messing/ https://www.kull-design.com/wasserhahn-classic/wasserhahn-13cm-40-593+631
but this fails
RewriteRule /wasserh?hne/wasserhahn-1-2-zoll-dg11040-e+1281 https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-dg11040-e+1281
I tried to escape the ?, but that doesn't help. I suspect that the part after the ? is seen as query string, so I attempted
RewriteCond %{QUERY_STRING} hne/wasserhahn-1-2-zoll-kurz-dg11040m+1277
RewriteRule ^/wasserh https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-kurz-dg11040m+1277 [R=301,L]
but that doesn't do the trick. There are similar questions, but they deal with real query strings.
Update:
I tested PanamaJacks solution using htaccess.madewithlove.be. It seems any url starting with wasserh is redirected to the same product. So i tried this instead
https://www.kull-design.com/wasserh?hne/wasserhahn-gebogen-dg110h76870+1295
RewriteEngine On
RewriteCond %{QUERY_STRING} ^hne/wasserhahn-gebogen-dg11010+1295
RewriteRule ^wasserh(.*)$ https://www.kull-design.com/wasserhaehne/wasserhahn-gebogen-dg11010+1295 [R=301,L]
but it doesn't match the condition. Again escaping - or + has no effect.
Update:
Note that you have to put these redirects before the RewriteRule, that sends anything to index.php or it won't work in spite of the rewrite-conditions being correct.
Actually this should work kinda. Give this rule a try and see if it works for you.
RewriteEngine On
RewriteCond %{QUERY_STRING} ^.+$
RewriteRule ^wasserh(.*)$ https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-kurz-dg11040m+1277? [R=301,L]
Edit:
Then just try matching part of it that is unique to that URL.
RewriteCond %{QUERY_STRING} ^hne(.+)1281$
RewriteRule ^wasserh(.*)$ https://www.kull-design.com/wasserhaehne/wasserhahn-1-2-zoll-kurz-dg11040m+1277? [R=301,L]

htaccess cannot match the whole URL

I am accessing the following URL:
http://example.com/welcome
Where I have the following .htaccess
RewriteEngine On
RewriteRule ^(.*)$ /index.php?package=base&page=$1 [L]
I am expecting to return
package=base
page=welcome
But instead is giving me a "500 Internal Server Error".
If I change the htaccess to
RewriteEngine On
RewriteRule ^we(.*)$ /index.php?package=base&page=$1 [L]
It returns:
package=base
page=lcome
As expected, and if I change the htaccess to
RewriteEngine On
RewriteRule ^(.*)me$ /index.php?package=base&page=$1 [L]
It returns:
package=base
page=welco
As I was expecting as well.
Now the question is... why it does not math the whole URL? What I am missing here? How can I say "take everything the user passes and put it on a variable"?
Thanks!
The rewrite engine loops, so without some sort of conditions, the regex ^(.*)$ matches index.php and so on. Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?package=base&page=$1 [L]

.htaccess rewrite rule causes endless loop

I want my .htaccess file to redirect to some page if any wildcard as a subdomain entry hit the browser. i.e. I want
sam.xyz.com
To redirect to
sam.xyz.com/view.php?id=sam
I am using following rewrite rules for redirect.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.xyz.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+).xyz.com
RewriteRule ^(.*)$ /view.php?id=%1 [L,R]
Problem i am facing is that it does not shift to new domain keeping query string instead it generates an endless loop
sam.xyz.com
redirects to
http://sam.xyz.com/view.php?id=sam
But doesnt move to url above without endless loop.
Kindly help me out.
Thanks in advance,
you should add a condition for redirect to prevent redirection loop:
RewriteCond %{REQUEST_URI} !^/view\.php
the whole code would be:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.xyz.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+).xyz.com
RewriteCond %{REQUEST_URI} !^/view\.php
RewriteRule ^(.*)$ /view.php?id=%1 [L,R]
You are redirecting to: prefix.domain.tld/view.php?id=prefix
Ensure that the url does not contain: id=prefix.
This solution prevents, that someone call's the url: aaa.example.com/view.php?id=bbb
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.xyz.com [NC]
RewriteCond %{HTTP_HOST} ^([^.]+).xyz.com
RewriteCond %1::%{QUERY_STRING} !^([^:]+)::.*id=\1
RewriteRule ^ /view.php?id=%1 [L,R]
Note: (.*) in the rewrite rule is obsolete.
Leave the R away to do not redirect the visitor to the url (/view.php?id=%1)