htaccess 中的多个重写规则如何修改 URL?
我想问一个问题,以便了解 Apache 如何处理重写 .htaccess 文件中指定的规则。
在我的网站上,我使用了一种经典的类别页面组织方式,每个类别都有多个部分:
http://www.mysite.com/category/section.html.
但是,没有 html 页面,所有内容都由pages.php 中的代码处理。使用简单的重写规则,像上面这样的 URL 会被映射到:
http://www.mysite.com/pages.php?cat=category&page=section
我决定将一个部分从 section1 重命名为 section1-xxx。为了满足对旧名称 (section1) 的请求,我添加了一个简单的规则来将 section1.html 映射到 section1-xxx.html 上。
我在 .htaccess 中添加的第一条规则如下:
R1
RewriteRule ^CAT1/section1.html$ CAT1/section1-xxx.html [NC]
,其中 CAT1 是类别的名称。
R2
RewriteRule ^CAT1/(.*).html$ pages.php?cat=CAT1&page=$1 [L,NC]
我的想法是先应用R1,然后应用R2。然而,当应用这些规则时,我最终会得到一个无法解释的(对于我的大脑来说)URL。
当请求以下页面时,
http://www.mysite.com/CAT1/section1.html
URL 首先被转换,
http://www.mysite.com/CAT1/section1-xxx.html/section1.html
然后
http://www.mysite.com/pages.php?cat=CAT1&page=section1-xxx.html/section1
出于好奇,我添加了 L (标志)来规则 R1:
RewriteRule ^CAT1/section1.html$ CAT1/section1-xxx.html [L,NC]
并且一切正常。现在 http://www.mysite.com/CAT1/section1.html 通过:
http://www.mysite.com/pages.php?cat=CAT1&page=section1-xxx
现在的问题是:
- 为什么我在将 L 标志添加到规则 R1 之前就获得了该 URL?
- L 标志应指示应用匹配规则,然后停止使用其他规则。但是,设置 L 标志后,R1 和 R2 都会应用。为什么?
感谢您抽出时间。
问候, 一个。
I would like to ask a question in order to understand how Apache processes rewrite rules specified in the .htaccess file.
On my site I used a classical organization of the pages in categories, each category having more than one section:
http://www.mysite.com/category/section.html.
However, there are no html pages, everything is processed by the code in pages.php. Using a simple rewrite rule, URLs like the one above are mapped onto:
http://www.mysite.com/pages.php?cat=category&page=section
I decided to rename a section from section1 to section1-xxx. In order to serve requests for the old name (section1), I added a simple rule to map section1.html on section1-xxx.html.
The first rules I added in the .htaccess were the following:
R1
RewriteRule ^CAT1/section1.html$ CAT1/section1-xxx.html [NC]
where CAT1 is the name of a category.
R2
RewriteRule ^CAT1/(.*).html$ pages.php?cat=CAT1&page=$1 [L,NC]
My idea was to apply R1 and then R2. However, when those rules are applied, I end up with an unexplainable (for my brain) URL.
When the following page is requested
http://www.mysite.com/CAT1/section1.html
the URL is first transformed in
http://www.mysite.com/CAT1/section1-xxx.html/section1.html
then in
http://www.mysite.com/pages.php?cat=CAT1&page=section1-xxx.html/section1
Out of curiosity, I added the L (flag) to rule R1:
RewriteRule ^CAT1/section1.html$ CAT1/section1-xxx.html [L,NC]
and everything worked fine. Now http://www.mysite.com/CAT1/section1.html is served via:
http://www.mysite.com/pages.php?cat=CAT1&page=section1-xxx
Now the questions:
- Why did I get that URL before adding the L flag to rule R1?
- The L flag should indicate to apply the matching rule and then stop using other rules. However, with the L flag set, both R1 and R2 are applied. Why?
Thanks for your time.
Regards,
A.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果我们不清楚模块的行为方式,[L] 标志可能会产生意想不到的结果。请注意,以下内容仅适用于在 .htaccess 文件中使用 mod_rewrite 时。 [L] 标志在 httpd.conf 中使用时的行为与预期完全一致。
L 标志将告诉 Apache 停止处理该请求的重写规则。现在经常没有意识到的是,它现在对新的重写文件名发出新请求,并再次开始处理重写规则。
因此,如果您要在目标仍然与模式匹配的情况下进行重写,则它将不会按预期运行。在这些情况下,您应该使用 RewriteCond 从规则中排除某个文件。
正如您所解释的,将 L 添加到 R1。(R1 将 some.html 重定向到某人.html,即您需要他们的 html 页面!)
The [L] flag can have unexpected results if we are not clear on how the module behaves. Note that the following only applies when mod_rewrite is used in a .htaccess file. The [L] flag behaves exactly as expected when used in httpd.conf.
The L flag will tell Apache to stop processing the rewrite rules for that request. Now what is often unrealised is that it now makes a new request for the new, rewritten filename and begin processing the rewrite rules again.
Therefore, if you were to do a rewrite where the destination is still a match to the pattern, it will not behave as desired. In these cases, you should use a RewriteCond to exlude a certain file from the rule.
As you explained add L to R1.(R1 redirects something.html to someone.html ie you nedd html page their!)
1) 您需要 R1 中的替换字符串中的起始 /
2) 正如 amolv 所说,您通过重写引擎进行了两次迭代,在第一种情况下,R1 和 R2 都匹配,并且重写的 url 在第二次迭代中没有匹配任何规则;将 L 添加到 R1,传入的 url 在第一次迭代中仅匹配 R1,在第二次迭代中仅匹配 R2。由于 R1 和 R2 中都以 / 开头,因此您不再需要 R1 中的 L。
我想知道“XXX”部分的内容;)
1) you need the starting / in the substitution string in R1
2) as said by amolv, you have two iterations through the rewrite engine, in the first case both R1 and R2 matched, and the rewritten url matched no rules in the second iteration; adding L to R1, the incoming url matched just R1 in the first iteration and just R2 in the second. With the starting / in both R1 and R2, you dont need the L in R1 anymore.
I'd like to know the contents of that section "XXX" ;)