Search code examples
.htaccesshttp-redirecthttp-status-code-301

Avoid infinite loop with 301 redirects


I'm using .htaccess to redirect

http://www.example.com/foo/

to

http://www.example.com/foo/bar

This is my code:

redirect 301 /foo/ http://www.example.com/foo/bar

However this produces a feedback loop, something like

http://www.example.com/foo/barbarbarbarbarbar etc.

I've tried placing delimiters around it:

redirect 301 ^/foo/$ http://www.example.com/foo/bar

but then the redirect simply doesn't take place. I'm probably missing some very simple point of syntax. Any ideas? Thanks.

EDIT

Here's my (almost) full .htaccess file:

RewriteEngine On
RewriteBase /

# Canonical is www version
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]

#redirect => http unless special page
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/(javascripts|images|library|stylesheets)
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

#redirect => https for special pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# send to router
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]

Solution

  • Have your rules like this:

    RewriteEngine On
    RewriteBase /
    
    # Canonical is www version
    RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
    RewriteRule ^ http://www.example.com%{REQUEST_URI} [L,R=301]
    
    #redirect => http unless special page
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{HTTPS} on
    RewriteCond %{THE_REQUEST} !/(javascripts|images|library|stylesheets)
    RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    #redirect => https for special pages
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{HTTPS} off
    RewriteRule !^index\.php$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
    
    RewriteRule ^foo/?$ /foo/bar [L,NC,R=301]
    
    # send to router
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.php [L]
    

    make sure to test this in a new browser or clear your browser cache before testing.