infinite loop while using modwrite in htaccess - .htaccess

What am trying to do in that code is:
Any visitor click on an href like http://domain.com/article.php?id=44 the .htaccess will transfer him to domain/article/44
then another rewrite rule to to get the content of requested id from the file article.php
RewriteCond %{QUERY_STRING} ^id=([^&]*)
RewriteRule ^article\.php$ http://alarabe.org/article/%1?
RewriteRule ^article/([a-z0-9\-]+)$ /article.php?id=$1 [L]

This rule isn't right and will certainly cause looping. You need to use THE_REQUEST variable that represents original request received by Apache from your browser.
Try this instead:
RewriteCond %{THE_REQUEST} \s/+article\.php\?id=([^\s&]+) [NC]
RewriteRule ^ http://alarabe.org/article/%1? [R=302,L]
RewriteRule ^article/([a-z0-9\-]+)$ /article.php?id=$1 [L]

Related

htaccess rewrite questions for modifying url structure and redirecting back

I have the following code:
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$
index.php?pageid=$1&pageid=$2&pageid=$3 [NC,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/$ index.php?
pageid=$1&pageid=$2 [NC,L]
RewriteRule ^([A-Za-z0-9-]+)/$ index.php?pageid=$1 [NC,L]
This makes the following happen:
When someone enters https://www.thegoodmarketer.co.uk/contact-us/ for example it loads the following page https://www.thegoodmarketer.co.uk/index.php?pageid=contact-us
What I want to achieve:
When someone enters https://www.thegoodmarketer.co.uk/index.php?pageid=contact-us I want it to automatically redirect to the correct URL structure: https://www.thegoodmarketer.co.uk/contact-us/
The same applies to all pages.
I've tried so hard to understand htaccess but I cannot get my head around it!
Very grateful for any help please.
Try with below it is for one example of your url, and use end flag on internal redirect rule to prevent recursive redirecting.
RewriteCond %{REQUEST_URI} ^/index.php
RewriteCond %{QUERY_STRING} ^pageid=([^/]+)$
RewriteRule ^ /%1 [QSD,R]
RewriteRule ^([A-Za-z0-9-]+)/$ index.php?pageid=$1 [NC,L,END]

.htaccess Rediret dynamic url to custom url

I have a URL structure like this
localhost/sumar/gallery.php?gen=slug-here
that i want to clean up for example: localhost/sumar/gallery/slug-here
so i need rewrite rule for this condition and prevent anyone from directly hitting the base URL http://localhost/sumar/gallery.php?gen=slug-here by auto redirecting it to localhost/sumar/gallery/slug-here
So far i have tried this method:
//that works
RewriteRule ^Gallery/([A-Za-z0-9-_]+)/?$ gallery.php?gen=$1
//below one does not seems to work
RewriteCond %{THE_REQUEST} ^GET\ /sumar/gallery\.php\?gen=([\w-]+) [NC]
RewriteRule ^sumar/gallery\.php$ /sumar/Gallery/%1? [R=301,L]
You'd need to act on the raw requests:
RewriteEngine On
RewriteRule ^(sumar)/Gallery/([\w-]+)/?$ /$1/gallery.php?gen=$1
RewriteCond %{THE_REQUEST} ^GET\ /sumar/gallery\.php\?gen=([\w-]+) [NC]
RewriteRule ^sumar/gallery\.php$ /sumar/Gallery/%1? [R=301,L]
PS: The character set [A-Za-z0-9_] can be represented with \w.

Apache Rewrite with variables in Query String

I have a two part problem that I have only been successful with the first part.
I have the following listed in .htaccess which works great:
RewriteRule ^senior/?$ demo.php?dID=1 [NC,L]
So visitors can go straight to mysite.com/senior and the correct internal page (demo.php?dID=1) gets pulled up.
My problem is that I also would like a rewrite where /demo.php?dID=1 shows up in the URL bar as /senior. So existing links show up with the new user friendly url.
My attempt so far has been:
RewriteCond %{QUERY_STRING} ^dID=1$
RewriteRule ^demo.php$ senior [NC]
RewriteRule ^senior/?$ demo.php?dID=1 [NC,L]
Thanks for your time and help.
You want to match against the request instead of the query string and redirect the browser:
RewriteCond %{THE_REQUEST} \ /demo\.php\?dID=1($|\ |&)
RewriteRule ^demo.php$ /senior? [NC,R]
RewriteRule ^senior/?$ /demo.php?dID=1 [NC,L]
Place this additional rule before your current rule:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+demo\.php\?dID=([^\s&]+) [NC]
RewriteRule ^ /senior? [R=302,L]
RewriteRule ^senior/?$ /demo.php?dID=1 [NC,L]
Your current rule based on QUERY_STRING will loop since internal rewrite rule will populate the QUERY_STRING and both rule will keep triggering each other.

htaccess rewrite for a rewritten URL that is already indexed by Google

Example:
1) URL (a poorly constructed one) is already indexed by Google:
www.abc.com/index.php?product=zzz
2) The URL is rewritten by using the following rewrite rule:
RewriteRule ^zzz$ index.php?product=zzz [L,NC]
The above is working fine, but we want to tell Google that the page has permanently moved from the URL in (1) URL www.abc.com/index.php?product=zzz to the URL in (2) www.abc.com/zzz
3) So now we apply the following rule above the rule (2):
RewriteCond %{QUERY_STRING} ^product=zzz [NC]
RewriteRule index http://www.abc.com/zzz? [L,R=301]
This results in an infinite loop. How do we tell Google that our site has changed from www.abc.com/index.php?product=zzz to www.abc.com/zzz? Or will Google do this by themselves?
-----Current full htaccess rules resulting in infinite loop:-----
RewriteCond %{QUERY_STRING} ^product=zzz [NC]
RewriteRule index http://www.abc.com/zzz? [L,R=301]
RewriteRule ^zzz$ index.php?product=zzz [L,NC]
Replace your existing rules with this code:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?product=([^\s&]+) [NC]
RewriteRule ^ /%1? [R=301,L]
RewriteRule ^(zzz)/?$ /index.php?product=$1 [L,NC,QSA]

htaccess 301 redirection using regular expression

This is my current .htaccess file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ $1/
RewriteRule ^([^/]+)/$ index.php?p1=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3&p4=$4 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ index.php?p1=$1&p2=$2&p3=$3&p4=$4&p5=$5 [L]
Basically, it takes up to five "Friendly url folders" and assign the value to varibles and then, send those to my index.php page
IE: http://www.example.com/ford/focus/grey/
$p1 = 'ford';
$p2 = 'focus';
$p3 = 'grey';
$p3 = 'grey';
So far, so good.
Now, I need to integrate a 301 instruction (RegExp?) in that same .htaccess because initially, I had GET parameters like this :
IE: http://www.example.com/ford/focus/grey/?lang=fr
I need to get rid of all GET variables because Google sees it as duplicate content (even if I'm using the nofollow attribute on my languages links)
IE: http://i.want.to.keep/my/url/?AND_DUMP_GET_VARIABLES
http://www.example.com/ford/focus/grey/?lang=fr
http://www.example.com/ford/focus/grey/?lang=en
http://www.example.com/ford/focus/grey/?lang=sp
==> http://www.example.com/ford/focus/grey/
Logically, the instruction should be interpreted between the first and the second block but I just don't know where to start. Any hints?
THANKS!
As I understand you want to get rid of the QUERY STRING and redirect (301 Permanent Redirect) to the same URL but without QUERY STRING.
The rule below will redirect EVERY request that has query string:
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1? [R=301,L]
1. The ? will do the magic -- will strip query string
2. You desperately need this line: RewriteCond %{ENV:REDIRECT_STATUS} ^$. The problem is that it may not work on your Apache setup and I cannot give you what exactly you need to make it work (it works fine on my vanilla Apache v2.2.17 on Windows).
After rewrite (internal redirect) occurred, it goes to next iteration and Apache starts matching all rules from the top again but for already rewritten URL. If we not add the above line, then mod_rewrite will apply the above rule to rewritten URL form and you will end up with all URLs get rewritten to /index.php with no parameters at all.
If the above will not work, then try the code below:
# do not do anything for already existing files and folders
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1? [R=301,L]
With help of # do not do anything for already existing files and folders rule, mod_rewrite will stop rewriting after URL will be rewritten to /index.php?p1=... format.
In case the above will not work at all (better -- in addition to the above -- I would suggest adding this anyway) use <link rel="canonical" href="FULL_PROPER_RUL"/> in your page:
http://googlewebmastercentral.blogspot.com/2009/02/specify-your-canonical.html
http://www.google.com/support/webmasters/bin/answer.py?answer=139394

Resources