simple 301 redirect with variable not working, why?

落花浮王杯 提交于 2020-01-11 11:59:28

问题


Here's what I got so far. The first part works but not the redirect itself.

What do I need to do to make it work?

RewriteEngine On
RewriteRule ^([^/\.]+)/?$ page.php?name=$1 [L]

RewriteRule ^page.php?name=([^/\.]+)/?$ /$1  [R=301,L] 

Also if I have multiple of these rules do I leave the [L] only on the last one?


回答1:


Besides the first rule overriding the second one, your second rule also won't work because you're trying to match the query string in a RewriteRule. Try something like this instead:

RewriteEngine On
RewriteBase /

RewriteCond %{QUERY_STRING} ^name=([^/.&]+)/?$
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^page\.php$ /%1?  [NS,R=301,L]

RewriteRule ^([^/.]+)/?$ page.php?name=$1 [NS,QSA,E=LOOP:1]

(I included the QSA flag so that an URL like /foobar?foo=bar will be rewritten to /page.php?name=foobar&foo=bar instead of just /page.php?name=foobar. If you don't want that, leave it out.)


Note: The second RewriteCond is there to keep the first rule from matching again after the second one has matched. The problem is that, in .htaccess context, mod_rewrite acts more or less as if all rules had the PT flag, causing the ruleset to be rerun from the start after every rewrite, even internal ones. Or, to quote the documentation:

"If you are using RewriteRule in either .htaccess files or in <Directory> sections, it is important to have some understanding of how the rules are processed. The simplified form of this is that once the rules have been processed, the rewritten request is handed back to the URL parsing engine to do what it may with it. It is possible that as the rewritten request is handled, the .htaccess file or <Directory> section may be encountered again, and thus the ruleset may be run again from the start. Most commonly this will happen if one of the rules causes a redirect - either internal or external - causing the request process to start over."

The workaround I'm using is to set a custom environment variable with E=LOOP:1 when the internal rewrite triggers, and check for it before doing the external rewrite. Note that, when the request processing restarts after the internal rewrite, Apache prepends REDIRECT_ to the names of all environment variables set during the previous pass, so even though the variable we set is named just LOOP, the one we need to check for is REDIRECT_LOOP.



来源:https://stackoverflow.com/questions/7812059/simple-301-redirect-with-variable-not-working-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!