开发者

How does one use mod_rewrite to "move" the appearance of a site directory to the root without actually moving the files? Spot the error in my code!

So, I have at site where I want pages such as;

www.example.com/shop/index.php

(or any other page under /shop/ for that matter.) to now appear as

www.example.com/index.php

but without actually moving the files, which are still located under /shop/ but are now accessed via urls at /

Seems simple enough, and I can do that on its 开发者_如何学Goown using a RewriteRule, pretty standard. The second requirement is to keep the links to the old content working, so I want a similar thing but in the other direction, but using a 301 external redirect (not rewrite), i.e.

www.example.com/shop/index.php

should 301 redirect to;

www.example.com/index.php

Again, simple enough on its own. But put the two together and you it gives you a lovely "This web page has a redirect loop" error when accessing a page. However, I don't understand why because one rule is a rewrite and one is a 301 redirect and they both have the L flag so I thought no more rules were processed. So, I am at the limit of my understanding of this mod_rewrite stuff.

To test, and avoid mucking up my site for people visiting, I am using the directories /blob/ and /b/ with /b/ being the new directory. The code I currently have that gives the redirect loop is;

RewriteRule ^blob/(.*)$ "http\:\/\/www\.example.com\/b\/$1" [R=301,NC,L]
RewriteRule ^b/(.*)$ /blob/$1 [NC,L]

I guess its because the first rule is being executed again once the second has, why is this if the 'L' flag is used? And what condition should I check or change to make so that the redirect rule only gets activated if the original request is for /blob/ not the rewritten URI.


Without any need of an extra query parameter you can use following rules in your .htaccess file:

Options +FollowSymlinks -MultiViews
RewriteEngine on

RewriteCond %{THE_REQUEST} ^GET\s/shop/ [NC]
RewriteRule ^shop/(.*)$ /$1 [R=301,NC,L]

RewriteCond %{REQUEST_URI} !^/shop/ [NC]
RewriteRule ^(.*)$ /shop/$1 [L]
  • First rule will send 301 to any request from /shop/foo to /foo in the browser, which is an external redirect
  • Second rule will internally redirect any /foo to /shop/goo without changing URL in the browser thus making sure your actual files are served from $DOCUMENT_ROOT/shop/ directory.


Try the following (I used your actual url examples):

RewriteEngine On

RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^shop/(.*)$ http://localhost/$1 [R=301,NC,L]

RewriteCond %{REQUEST_URI} !^\/shop\/
RewriteRule ^(.*)$ /shop/$1?rewrite [NC,L,QSA]

The issue you are running into is that when mod_rewrite does the rewrite it is actually performing an Internal Redirect, which causes the rules to applied again. So, this means you have to protect against that, in this case, I've added a parameter rewrite to the URL that the redirect checks for.

Hope that helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜