Rewrite a url string to corresponding folders - regex

I want to have beautiful url and at the same time hide my folder structure,
I want the first Url to point to second Url,
image/f1_f2_girl.jpg
img/f1/f2/girl.jpg
I tried following but it did not work;
RewriteRule ^image\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)$ img\/$1\/$2\/$3
how can I do Such using htaccess?

You regex needs to match for underscores in the regex pattern:
RewriteEngine On
# disable direct access:
RewriteCond %{THE_REQUEST} \s/+img/[^/]+/[^/]+/.+?\.jpg\s [NC]
RewriteRule ^ - [L,R=404]
RewriteRule ^image/([^_]+)_([^_]+)_(.+?\.jpg)$ /img/$1/$2/$3 [L,NC,R=302]

In your first URL you have _ not /.
And final .jpg (with .)
RewriteRule ^image/([a-z0-9]+)_([a-z0-9]+)_([a-z0-9.]+)$ img/$1/$2/$3 [NC,L]

Related

Query string not redirected on deeper level directories

I want to redirect each link with a query string to a specific address by appending the string. I have the following in my WordPress .htaccess:
RewriteEngine On
RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
RewriteRule (.*) catid%1? [R=301,L]
When a user hits example.com/?catid=10, they are successfully redirected to example.com/catid10, which is what I want.
However, when they go a directory deeper (example.com/category/?catid=10), they are not redirected to example.com/category/catid10.
I have been reading manuals but can't find the answer.
Edit
If this is helpful, this is what WordPress has defined in my htaccess:
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Providing RewriteBase / is already defined (which it normally is with WordPress and must be if your existing redirect is working) then you can do it like the following with a single rule:
RewriteCond %{QUERY_STRING} (?:^|&)catid=(\d+) [NC]
RewriteRule (.*?)/?$ $1/catid%1 [QSD,R=301,L]
The capturing group (.*?) is non-greedy so does not consume the optional trailing slash that follows.
Requests for the document root do not require RewriteBase, but all "deeper" URLs do, since the resulting substitution string will otherwise be a relative URL.
The non-capturing (?:^|&) prefix on the CondPattern ensures that it only matches the URL parameter name catid and not foocatid etc.
You just need to add the captured group from (.*) to your redirect target using $1. I'd break it up into a few rules so that you don't get duplicated slashes. Rather then ending your rewrite targets with a question mark, I would add the QSD (query string discard) flag to the rule. I would also add starts with (^) and ends with ($) to rewrite rule so you always match the whole thing. I also like to start my rules with an optional slash (/?) so that the rules can be used in both .htaccess and apache conf.
RewriteEngine On
# Home URL with catid query string
RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
RewriteRule ^/?$ /catid%1 [R=301,L,QSD]
# Deep URL ending in slash with a catid query string
RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
RewriteRule ^/?(.*)/$ /$1/catid%1 [R=301,L,QSD]
# Deep URL not ending in slash with a cadid query string
RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
RewriteRule ^/?(.*)$ /$1/catid%1 [R=301,L,QSD]

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]

.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

removing multiple groups of slashes everywhere in URL in .htaccess

I currently have a website where guests are able to access each url with any number of slashes to separate folder names. For example, if a URL is supposed to be:
http://example.com/one/two/three/four
Then users could access the same page via any of the following:
http://example.com/one//two///three////four/////
http://example.com/one/two////three/four/////
http://example.com///one///////////two////three/four/
http://example.com///////////one///////////two/three/four
However, I want the above example urls to only redirect users to this URL:
http://example.com/one/two/three/four
This is my .htaccess file to attempt to stop the enormous slashes:
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]
RewriteRule ^(.*)/+$ /$1 [R=301,L,NC]
RewriteCond %{REQUEST_URI} ^/+(.*)/+$
RewriteRule .* /%1 [R=301,L]
The third line successfully stops trailing slashes on long URLs. The 4th and 5th lines are my attempt to stop trailing slashes right after the domain name, but that was unsuccessful.
The reason why I ask this question is because I don't want google to catch me for duplicate content and with adsense active on the site, google will likely scan all the URLs that I access.
Is there a RewriteCond/RewriteRule combo I can use to strip the middle slashes or is it more involved?
You can use this rule for removing multiple slashes anywhere in URL except query string:
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=302,L,NE]
This works for me:
RewriteCond %{REQUEST_URI} ^(.*)//(.*)$
RewriteRule . %1/%2 [R=301,L]