Apache url rewriting and loop - regex

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]

Related

htaccess - rewrite URL ending with specific string and capturing the unique part

I want to feed several URLs into a single php file that will handle the contents of the page, the URLs are like
domain.com/fashion-registration
domain.com/singing-registration
I want to capture URLs ending with -registration and feed fashion or singing into the page but it doesn't seem to be working. This is what I tried
RewriteRule ^(.*)$-registration category.php?link=$1 [NC,L,QSA]
Could you please try following.
RewriteEngine ON
RewriteCond %{REQUEST_URI} ^/(.*)-registration/?$ [NC]
RewriteRule ^(.*)$ /category.php?link=%1 [NE,NC,L]
OR you could try following too, one without RewriteCond.
RewriteEngine ON
RewriteRule ^(.*)-registration/?$ /category.php?link=$1 [NE,NC,L]
Problem in OP's attempt: Since you have used ^(.*)$ and after that you are using -registration in your regex that's why your regex is NEVER going to match -registration

RegEx matching for URL redirect in htaccess

I've some dynamic urls. If I took a url with a query parameter, it leads to 404 page. So I would like to do a redirection using htaccess. I tried with a matching url pattern regex and it is not redirecting.
Url structure will be /detail/2019-12/news/news-title-12-2019.html?something and which I need to redirect to /detail/2019-12/news/news-title-12-2019.html
I tried something like this, but it is not redirecting;
RewriteCond %{QUERY_STRING} .
RewriteRule ^detail/\d{4}-\d{2}/news/(?=\S*['-])([a-zA-Z0-9'-]+\.html)\?\S*$ %{REQUEST_URI}? [NC,L,R=301]
How do I solve this problem?
This RegEx might help you to write your RewriteRul:
^(.+\.html)(\?.+)$
I'm not quite sure, but your code might look like:
RewriteCond %{QUERY_STRING} .
RewriteRule ^(.+\.html)(\?.+)$ http://domain_goes_here/$1 [NC,L,R=301]
RewriteCond %{QUERY_STRING} .
RewriteRule ^(.+\.html)(\?.+)$ http://domain_goes_here/$1 [NC,L,R=302]
You also might need to:
restart apache
delete your browser cache
If you wish to add boundaries to your expression, this RegEx might help you to do so:
^(\/detail\/[0-9-]+\/news\/[a-z0-9-]+\.html)(\?.+)$
Code:
RewriteCond %{QUERY_STRING} .
RewriteRule ^(\/detail\/[0-9-]+\/news\/[a-z0-9-]+\.html)(\?.+)$ http://domain_goes_here/$1 [NC,L,R=301]
RewriteCond %{QUERY_STRING} .
RewriteRule ^(\/detail\/[0-9-]+\/news\/[a-z0-9-]+\.html)(\?.+)$ http://domain_goes_here/$1 [NC,L,R=302]
The reason why you rule isn't working is because you are checking Querystring ? in your rule regex. The pattern of RewriteRule is for URL path only .
The following should work for you
RewriteCond %{QUERY_STRING} .
RewriteRule ^detail/\d{4}-\d{2}/news/ %{RRQUEST_URI}? [L,R=301]
Make sure to clear your browser cache or use a different browser for testing this.

.htaccess redirects aren't respecting my 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

.htaccess RewriteRule outputs wrong parameter result

I am trying to use .htaccess RewriteRule to beautify some urls, but I've got a problem that I can't fix.
I've written this:
RewriteEngine On
RewriteRule ^(.*)/(foro|forum)$ code/forum/forum.php?id=$1
RewriteRule ^(.*)/(foro|forum)/(.*)$ code/forum/forum.php?id=$1&subf=$3
RewriteRule ^(.*)/(foro|forum)/(.*)/(.*)$ code/forum/forum.php?id=$1&subf=$3&post=$4
The first url rewrite works properly, showing as result the id parameter (I.e. localhost/web/user501/forum -> id=user501).
It happens the same with the second one (localhost/web/user501/forum/3 -> id=user501, subf=3).
But when I try the third url rewrite, somehow the output id is not 'user501' as I expect, but 'code/forum/forum.php'.
The output of the other vars is normal (localhost/web/user501/forum/3/5 -> id=code/forum/forum.php, subf=3, post=5).
I tried to change the first (.*) on that url rewrite for a fixed word... it worked, but unfortunately I need it to be a changeful word.
Does someone know what's happening?
That is because ^(.*)/(foro|forum)/(.*)/(.*)$ pattern also matches code/forum/forum.php hence RewriteRule runs again and gives you wrote results.
Try this code:
RewriteEngine On
# ignore /code/forum/forum.php
RewriteRule ^code/forum/forum\.php$ - [L,NC]
RewriteRule ^(.*)/(foro|forum)$ code/forum/forum.php?id=$1 [L,QSA]
RewriteRule ^(.*)/(foro|forum)/(.*)$ code/forum/forum.php?id=$1&subf=$3 [L,QSA]
RewriteRule ^(.*)/(foro|forum)/(.*)/(.*)$ code/forum/forum.php?id=$1&subf=$3&post=$4 [L,QSA]

.htaccess rewrite rule with multiple {QUERY_STRING}s

I am working on a website project where we basically move from TYPO3 to a WordPress & Magento-solution.
Before launching the new site, I would like to add rewrite rules to point the old (TYPO3, non-SEF) URLs to the corresponding new ones. I have an Excel-list with around 1000 URLs that I somehow would like to add to htaccess and create 301's.
If you have a better approach for this, I'd be thankful.
What I am struggling with is:
The "old" URL structure looks something like ?id=123\&user_e15proddb1_pi1[domain]=42
the correcponding new URL would be
/de/alle-produkte/neuheiten.html
RewriteEngine is on, RewriteBase is /.
I tried
RewriteCond %{QUERY_STRING} ^id=123\&user_e15proddb1_pi1[domain]=42$
RewriteRule . /de/alle-produkte/neuheiten.html [R=301,L]
With additionally escaping the _and the [] with no avail.
I tried to seperate the {QUERY_STRING}s into two by
RewriteCond %{QUERY_STRING} ^id=123$
RewriteCond %{QUERY_STRING} ^user_e15proddb1_pi1[domain]=42$
followed by TheRule. Also no avail.
Rewriting itself works, because I tried
RewriteRule .id=123\&user_e15proddb1_pi1\[domain\]=42$ /de/alle-produkte/neuheiten.html [R=301,L]
But that only works without the question mark in the beginning.
Could you give me a hint on what I am doing wrong?
You can use this rule by escaping [ and ]:
RewriteCond %{QUERY_STRING} ^id=123&user_e15proddb1_pi1\[domain\]=42$
RewriteRule ^ /de/alle-produkte/neuheiten.html? [R=302,L]
Also note ? at the end of target URI to strip off any existing query string to prevent a redirect loop.
I got a solution to and made this one work:
RewriteCond %{QUERY_STRING} ^id=123\&user\_e15proddb1\_pi1\[domain\]=42$
RewriteRule (.*) /de/alle-produkte/neuheiten.html? [R=301,L]
Proably something with escaping those characters was going wrong when I tried over and over again.