I have the following file:
/forums/faq.php -- at http://www.domain.com/forums/faq.php
I would like calls to this file (which are usually done in the form of faq.php?faq=faqname) to be rewritten as:
/faq/faqname -- at http://www.domain.com/faq/faqname
I've been trying the following .htaccess rules to no avail. On my root .htaccess:
RewriteRule ^forums/faq.php?faq=(.*)$ faq/$1 [L,R=301]
RewriteRule ^faq$ faq/ [L,QSA,R=301]
On my /forums/.htaccess:
RewriteRule ^faq.php?faq=(.*)$ http://www.domain.com/faq/$1 [L,R=301]
Could I be overlooking something really obvious here? Is my syntax off?
You can ditch the rules in the /forums/ htaccess, the rules there have precedence over rules in the document root. You don't need them in both places.
Your rules will cause a redirect loop if they did what you wanted.
You can't match against the query string in a RewriteRule, so the first rule won't match anything. What you really want to do is match against the actual request.
# redirect /forums/faq.php?faq=faqname to /faq/faqname
RewriteCond %{THE_REQUEST} \ /forums/faq\.php\?faq=([^&\ ]+)
RewriteRule ^forums/faq.php$ /faq/%1? [L,R=301]
Then you need to internally change it back
RewriteRule ^faq/(.+)$ /forums/faq.php?faq=$1 [L,QSA]
Related
I'm trying to convert the following NGINX rule:
location ~ "^/calendrier/[0-9]{4}" {
rewrite ^/calendrier/(.*)$ /calendar/$1;
}
to .htaccess. I tried:
RewriteCond ^/calendrier/[0-9]{4} [NC]
RewriteRule ^/calendrier/(.*)$ /calendar/$1 [QSA,L]
but it isn't working.
Please help.
Thanks
You need to review the mod_rewrite documentation before attempting to convert rules from other platforms. Reason being: it is essential that you understand exactly how mod_rewrite should be used so that conversions are painless.
The problem with your conversion is that the RewriteCond is not checking that pattern against anything. Essentially, you've just done guess-work to see if it does what you want.
You only need to place the following in your /.htaccess file:
RewriteEngine on
RewriteRule ^calendier/([0-9]{4})/?$ /calendar/$1 [L]
The first part of the rule checks for calendier/<some_number> with an optional trailing slash (If you do not want the slash, you can remove /?).
This is the rewrite I used to get the job done.
RewriteCond %{REQUEST_URI} ^/calendrier/ [NC]
RewriteRule ^calendrier/(.*)$ /calendar/$1 [NC,L]
I have problem when I try to redirect and rewrite together.
I have site example.com/show_table.php?table=12 (max 99 tables). I wanted nice links, so I got this .htacces rw rule:
RewriteRule ^table/([0-9]{1,2})$ show_table.php?table=$1 [L,NC]
Now are links something like example.com/table/12 - it's definitely OK. But I want all old links redirect to new format. So I use Redirect 301, I added to .htaccess this code:
RewriteCond %{REQUEST_URI} show_table.php
RewriteCond %{QUERY_STRING} ^table=([0-9]{1,2})$
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
But when I visit example.com/show_table.php?table=12, I receive just redir-loop. I don't understant - the first is rewrite, the second is redirection, there ain't no two redirections. Do You see any error?
Thanks!
Instead of checking REQUEST_URI in the condition, you need to be checking in THE_REQUEST (which contains the full original HTTP request, like GET /show_table.php HTTP/1.1). When Apache performs the rewrite, it changes REQUEST_URI, so to the rewritten value, and that sends you into a loop.
# Match show_table.php in the input request
RewriteCond %{THE_REQUEST} /show_table\.php
RewriteCond %{QUERY_STRING} ^table=([0-9]{1,2})$
# Do a full redirection to the new URL
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
# Then apply the internal rewrite as you already have working
RewriteRule ^table/([0-9]{1,2})$ show_table.php?table=$1 [L,NC]
You could get more specific in the %{THE_REQUEST} condition, but it should be sufficient and not harmful to use show_table\.php as the expression.
You'll want to read over the notes on THE_REQUEST over at Apache's RewriteCond documentation.
Note: Technically, you can capture the query string in the same RewriteCond and reduce it to just one condition. This is a little shorter:
# THE_REQUEST will include the query string so you can get it here.
RewriteCond %{THE_REQUEST} /show_table\.php\?table=([0-9]{1,2})
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
i have wildcard subdomains sets already and works fine, now i wish have friends url for the content in thats subdomains, the structure of my site is if the user type subdomain.maindomain.com and the .htaccess redirect to
blogs/index.php?user=subdomain
where blogs/index.php receive the param and show the correct content
now i try to make the url function like this
subdomain.maindoamin.com/24/title-of-content
and then .htaccess must result
blogs/index.php?id_content=24&title=title-of-content
i have the next .htaccess
Options +FollowSymLinks
#this force to server the content always without www.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule ^(.*)$ http://%1/$1 [R=301]
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteRule ^(.*)$ blogs/index.php?url=%1 [QSA,L]
#the next line i can't make work to make nice url
RewriteRule ^/(.*)/(.*)$ blogs/index.php?idP=$1&name=$2 [L]
not working because when i make in index.php
echo $_SERVER['REQUEST_URI'];
don't show idP=24 show /24/title-of-content and i need $_GET(idP)
i really apreciate some light on this stuff i am not expert on htaccess, thanks in advance to everybody.
There are two problems:
The first argument of RewriteRule matches against everything after the slash of the directory .htaccess is in, and before the query string. If .htaccess is in your www-root, and you get the url http://www.example.com/shiny/unicorns.php?are=shiny, you match against shiny/unicorns.php. It will never start with a slash, so ^/ will never match.
Rules are executed in order. If you go to http://sub.example.com/10/unicorns, the second rule will match first and rewrite the request to /blogs/index.php?url=10/unicorns. If you removed the leading slash the third rule would match, but normally you wouldn't want that. You want to have the third rule only match
You want to move the third rule up so it is the second rule. You want to make it more specific to only match with subdomains. You also know the first part contains only numbers, so use that knowledge to prevent blogs/index.php from matching your now second rule. You also need to prevent blogs/index.php from matching the now third rule to prevent it from matching itself. Last but not least I removed [L] from the now second rule, since the third rule will match anyway.
#the next line i can't make work to make nice url
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^([0-9]+)/([^/]+)$ blogs/index.php?idP=$1&name=$2
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteCond %{REQUEST_URI} !/blogs/index\.php
RewriteRule ^ blogs/index.php?url=%1 [QSA,L]
I have the following problem. The link format below no longer exist:
photos.domain.com/web/poppic.php?n=[any number from 0 to the roof]
Ej,: photos.domain.com/web/poppic.php?n=30
I replaced it, a year ago, to just: photos.domain.com/
Years after, I am still having tons of 404 errors.
I need a permanent redirect, and an htaccess difective for search engines to do not follow and to no longer index that old link.
I tried rewriterule ^web\/poppic\.php?n=30 "http\:\/\/photos\.domain\.com" [R=301,L] will work. HOWEVER, I requires to write each line, from 0 to 9999999999999999999999999:
rewriterule ^web\/poppic\.php?n=0 "http\:\/\/photos\.domain\.com" [R=301,L]
rewriterule ^web\/poppic\.php?n=1 "http\:\/\/photos\.domain\.com" [R=301,L]
rewriterule ^web\/poppic\.php?n=2 "http\:\/\/photos\.domain\.com" [R=301,L]
etc.
How can I do it with a variable, to replace php?n=[number] for php?n=$variable (Or something like that)?
Also, it is not telling crawlers to do not follow/index the page.
Could you please help?
You can't match against the query string inside of a rewrite rule using apache's mod_rewrite. You need to use a rewrite condition and match against the %{QUERY_STRING} variable:
RewriteCond %{QUERY_STRING} ^n=[0-9]+
RewriteRule ^web/poppic\.php$ /? [L,R=301]
Not sure how your original rule:
rewriterule ^web\/poppic\.php?n=30 "http\:\/\/photos\.domain\.com" [R=301,L]
ever worked. It doesn't work for me under apache 2.2 or 2.4.
I need to redirect
/search?keywords=somesearchterm
to
/search/somesearchterm
This seems incredibly basic but I've been pounding my head against it for an hour.
Thanks for taking the time to look at this.
You want to implement what is called a "301 Redirect" with mod_rewrite.
RewriteEngine ON
RewriteRule ^/search\?keywords=somesearchterm$ /search/somesearchterm
adding regular expressions:
RewriteEngine ON
RewriteRule ^/search\?keywords=(.+) /search/$1 [R=301,L]
R=301 means provide a 301 Header redirect so the user's URL changes in the browser, and L means don't process any more rewrite rules if this one matches.
If you want to do the reverse -- in other words, if someone goes to mysite.com/search/asearchterm and you want the URL to stay the same, but "behind the scenes" you want it to load a certain server script, do this:
RewriteEngine ON
RewriteRule ^/search/(.+) /search.php\?keywords=$1 [L]
You can not match aginst Query string in RewriteRule directive. Use %{THE_REQUEST} or %{QUERY_STRING} server variables to match the Query string :
The following rule works fine for this redirection
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/search\?kewords=([^&\s]+) [NC]
RewriteRule ^ /search/%1? [NE,NC,R,L]
RewriteRule ^search/([^/]+)/?$ /search?keyword=$1 [QSA,NC,L]