.htaccess redirects aren't respecting my regex - regex

I need to redirect any requests with query strings from a set of origin URLs back to a thank you page.
For example, I need to redirect:
http://example.com/test1/test2/[origin]/?id=1
back to
http://example.com/thank-you
The way I've got it set up in my .htaccess file is as such:
RewriteEngine On
RedirectMatch 302 ^/test1/test2/(.*)/.+ /thank-you
I've tested the regex I'm using in an online regex tester and it appears to work as expected, so I'm confused as to why the redirect isn't taking place. Here's the link to that.
Obviously, I had to add backslashes to escape the slashes in the URL in the regex tester, but based on my understanding of how .htaccess evaluates regex, these aren't necessary.
My question is: the redirect works perfectly from the page without the query string if I remove the .+ from the end of the regex string, meaning that the beginning part of the regex works fine. I don't understand why the query string isn't matching the regex I've created.
I have also tried:
RewriteCond %{REQUEST_URI} ^/test1/test2/(.*)/
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule (.*) /thank-you [R=302,L]

For your RedirectMatch, you may use:
RedirectMatch 302 ^/test1/test2/(.*)/(.*)+ /thank-you?
For your RewriteRule section, you may use:
RewriteCond %{REQUEST_URI} ^/test1/test2/(.*)/
RewriteCond %{QUERY_STRING} id=([0-9]+) [NC]
RewriteRule (.*) /thank-you [R=302,L,QSD]

First , no need to RewriteEngine On with mod_alias which is RedirectMatch at your rules use it with mod_rewrite , the second rules .
Try this :
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ [NC]
RewriteRule ^test1/test2/[^\/]+/$ /thank-you? [R=302,L]
I use ^id=([0-9]+)$ to restrict query string for a one that start with id and end with numerical value.
I remove this line RewriteCond %{REQUEST_URI} ^/test1/test2/(.*)/ becasue you could match against URI in RewriteRule as well.
If this rules wrok , change [R=302,L] to [R=301,L] to be permanent redirection.
Note: clear browser cache then test

Related

How to redirect any URL that contains 2 forward slashes to the homepage via .htaccess?

I need to redirect any URL that contains 2 or more forward slashes in a row back to the homepage.
I have tried:
RewriteRule example.com(.*)// https://example.com [R,L]
But it does not work and I don't understand why as it is pretty straightforward.
How can I do this?
Here is how you can achieve this (assuming /home is the path to your homepage. remove it in the RewriteRule if domain root is your homepage) :
RewriteEngine On
RewriteCond %{REQUEST_URI} //
RewriteRule ^(.*)$ %{SERVER_PROTOCOL}://%{HTTP_HOST}/home [R,L]
Explanation
RewriteCond %{REQUEST_URI} Condition is met if request uri contains a double slash. The slash does not need to be escaped (preceeded with \) as it carries no special meaning in the regex
RewriteRule ^(.*)$ %{SERVER_PROTOCOL}://%{HTTP_HOST}/home Rewrite the url and redirect to http(s)://yourdomain/home
Demo

Apache url rewriting and loop

setting url rewriting to have nice urls, i have existing urls like that :
/xxx/test.php
but in the background, it is allways going to the same script with a query :
/xxx/index.php?id=test
with the following rewrite :
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]
it's working fine.
now, there are old urls still like /xxx/index.php?id=$1
and i want to get rid of these old urls, meaning I want all of them to be for the users like /xxx/test.php with a 301 redirect
i did a rewrite for this but then i'm entering a loop despite the L flag
RewriteCond %{QUERY_STRING} ^id=(.*)$
RewriteRule ^xxx/index\.php$ /xxx/%1.php? [R=301,L]
? is it possible to handle that and how ?
and other to describe it is allways use the script :
/xxx/index.php?id=$1
but allways have the right url in the browser displayed
Keep your existing
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]
which appears to work fine.
Add in these two lines before that which will catch if there is an id= and strip it out of the URL.
RewriteCond %{QUERY_STRING} ^id=([^&]*)(.*)$
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=%1%2 [L,R=301]
^ start of query string
([^&])* any character except &
(.*) any following characters
So if query string is id=test&something=else RewriteRule will append exactly that and nothing else as there is no more QSA flag.
Try those 3 lines together (htaccess test website), here is the full htaccess file:
RewriteCond %{QUERY_STRING} ^id=([^&]*)(.*)$
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=%1%2 [L]
RewriteRule ^xxx/([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]
Make your RewriteRule not match index.php or remove the QSA flag.
Say you type test.php well now you will go to index.php?id=test
Then Rewrite occurs again and you will go to index.php?id=index&id=test
Then it will occur again because the page is different: index.php?id=index&id=index&id=test etc.
So add in your regex a negative lookahead: xxx/(?!index)([0-9a-z\-]*)\.php
Try:
RewriteRule ^xxx/(?!index)([0-9a-z\-]*)\.php$ /xxx/index\.php?id=$1 [QSA,L]

Remove multiple trailing slashes in root using htaccess

I have a rule in my htaccess file to remove any extra trailing slashes from a url, this works on sub-directories with any more than 1 trailing slash. However it doesn't work on the root; which i need it to do.
For example.
http://www.example.com/test//// Redirects to http://www.example.com/test/
http://www.example.com/// Needs to redirect to http://www.example.com
Any ideas on what i need to add?. Cheers.
RewriteCond %{REQUEST_URI} ^(.*?)(?:/){2,}$
RewriteRule . %1/ [R=301,L]
For removing multiple slashes anywhere in REQUEST_URI this rule works best:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=301,L,NE]
It takes advantage of the fact that mod_rewrite engine itself converts all multiple forward slashes to a single slash in the RewriteRule pattern. We use RewriteCond %{THE_REQUEST} to make sure original REQUEST_URI contains multiple slashes.
Here [^?]*// matches 2 // before matching query string since [^?] matches anything except ?. This will allow // in query string.
Try with:
RewriteCond %{REQUEST_URI} ^(.*?)//+$
RewriteRule ^ %1/ [R=301,L]
You htaccess works great as you can test on below link
https://htaccess.madewithlove.be/
So you need to make sure you test either with a Chrome Incognito window or using like below
curl -v http://example.com////
I usually prefer curl as I know it will give a fresh response from the server always
You just need two rule to match two different pattern
RewriteCond %{REQUEST_URI} ^(?:/){2,}$
RewriteRule . / [R=301,L]
RewriteCond %{REQUEST_URI} ^(.*?)(?:/){2,}$
RewriteRule . %1/ [R=301,L]

htaccess Rewrite Rules appending parameter?

Our original urls began with a parameter and the following rewrite works to redirect them (thanks to Jon Lin).
However, the original parameter is being appended to redirect, so that
RewriteEngine On
RewriteCond %{QUERY_STRING} ^old-page$
RewriteRule ^$ /newpage [R=301,L]
ends up going to mydomain.com/newpage?old-page
Any idea how to fix? thanks again,
Geoff
Have it like this to strip off existing query string:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^old-page$ [NC]
RewriteRule ^$ /newpage? [R=301,L]
Take note of ? at the end of target URI, that is used to strip-off existing query string.

How to Redirect Subdomains to Other Domain

What I'm trying to accomplish with htaccess mod-rewrite:
Redirect all sub-domains to new domain name w rewrite rule.
e.g.
test1.olddomain.com ===> test1.newdomain.com
test2.olddomain.com ===> test2.newdomain.com
test3.olddomain.com ===> test3.newdomain.com
This is what I have so far which of course is wrong:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^olddomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.olddomain\.com$ [NC]
RewriteRule ^(.*) http://www.newdomain.com/$1 [R=301,L]
RewriteRule [a-zA-Z]+\.olddomain.com$ http://$1.newdomain.com/ [R=301,L]
Since I'm not a Regular Expression junkie just yet, I need your help... Thanks for any help you can give here. I know also we can compile these first two conditions into one.
Note: The reason I don't redirect all domain using DNS is that a lot of directories need special rewrite rules in order to maintain positions on SEO.
In .htaccess files, the "URL" that RewriteRules match has been stripped of the domain name and any directories that led to the current directory. (Using mod_rewrite in .htaccess files is a huge pain; if you have access to the server conf do it there instead!!)
So, assuming that your .htaccess is in your DocumentRoot, try something like this:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)olddomain\.com$ [NC]
RewriteRule ^(.*)$ http://%1newdomain.com/$1 [R=301,L]
The %1 is supposed to match the first group in the RewriteCond and the $1 is supposed to match the URL part.
RewriteRule ^(.+)\.olddomain\.com$ http://$1.newdomain.com/ [R=301,L]
You need to specify the ^ at the beginning to ask the regex engine to match a line beginning there. Next, you match anything before ".olddomain.com" and assign that to the first matched pattern (which will later be accessible in $1). You need to surround with parentheses (.+) in order for the match to be assigned to $1.