本文介绍了重写问题 - L(ast) 不被尊重?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我正在为一个站点开发一个 CSS/JS 压缩系统,它基本上具有以下 htaccess

So I'm working on a CSS/JS compressing system for a site, that has basically the following htaccess

RewriteEngine On

...

RewriteRule ^css/images/(.*)$ images/site/$1?%{QUERY_STRING} [L]
RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L]

RewriteCond %{HTTP_HOST} ^www.site.com [NC]
RewriteRule ^(.*)$ http://site.com/$1 [L,R=301]

RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]

php_flag register_globals off
php_flag magic_quotes_gpc off
php_flag register_long_arrays off

# 404 Handler
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1&%{QUERY_STRING}

现在 assets.php 没有收到哈希调用,而是 index.php - 如果我删除 RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]

Right now assets.php isn't receiving the hash call, but rather index.php - if I remove the line RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]

它工作正常,但我不知道为什么 - 资产上的 [L] 标志不应该重写 RewriteRule ^css/([0-9a-fA-F]{32})$ 资产.php?hash=$1 [L] 阻止执行任何进一步的重写?我对这里发生的事情感到困惑.

it works fine but I don't know why - shouldn't the [L] flag on the assets rewrite RewriteRule ^css/([0-9a-fA-F]{32})$ assets.php?hash=$1 [L] prevent any further rewrites from being executed? I'm confused by whats happening here.

如果您对此有所了解,我们将不胜感激.

Any light you could shed on this would be much appreciated.

推荐答案

L 标志表示不再执行规则集中的任何规则",奇怪的是,这并不意味着不再有规则将由 mod_rewrite 执行.

The L flag says "do not execute any more rules in the ruleset," which oddly enough does not imply that no more rules will be executed by mod_rewrite.

当您在每个目录上下文中指定 mod_rewrite 指令时,例如使用 .htaccess 或服务器或虚拟服务器的 Directory 部分配置,重写在 Apache 处理阶段后期进行.要在这里发挥它的魔力,mod_rewrite 必须在每次重写您的 URL 时执行内部重定向.

When you specify mod_rewrite directives in a per-directory context, like with .htaccess or the Directory section of a server or virtual server configuration, the rewrite comes late in the Apache processing stage. To do its magic here, mod_rewrite has to perform an internal redirect every time that your URL is rewritten.

由于您的重写可能将您指向不同的目录,mod_rewrite 将自己指定为此重定向的处理程序,以便它可以通过它在您发送的新位置可能找到的任何规则请求.通常,由于您只处理根目录中的一个 .htaccess 文件,新"位置中的规则恰好是导致重写的那些规则.

Since your rewrite could point you to a different directory, mod_rewrite assigns itself as the handler for this redirection so that it can go through whatever rules it may find at the new location you've sent the request to. Often, since you're only dealing with a single .htaccess file in your root, the rules in the "new" location happen to be the ones that caused the rewrite in the first place.

因此,在您的情况下,会发生以下情况:

So, in your case, the following happens:

  • 请求 /css/A01EF
  • mod_rewrite 启动规则集
  • ^css/([0-9a-fA-F]{32})$ ->assets.php?hash=A01EF
  • L 标志停止重写并强制内部重定向到 assets.php?hash=A01EF
  • mod_rewrite 重新开始规则集
  • ^([a-zA-Z0-9_.-]+)$ -> index.php?url=assets.php&hash=A01EF(你顺便说一下,这里可以使用 QSA)
  • L 标志停止重写并强制内部重定向到 index.php?url=assets.php&hash=A01EF
  • Request made for /css/A01EF
  • mod_rewrite starts the ruleset
  • ^css/([0-9a-fA-F]{32})$ -> assets.php?hash=A01EF
  • L flag stops rewrite and forces internal redirect to assets.php?hash=A01EF
  • mod_rewrite starts the ruleset over again
  • ^([a-zA-Z0-9_.-]+)$ -> index.php?url=assets.php&hash=A01EF (you could use QSA here, by the way)
  • L flag stops rewrite and forces internal redirect to index.php?url=assets.php&hash=A01EF

这个循环很可能会继续,但 mod_rewrite 认识到您正在重定向到同一页面并在此之后忽略您的重写.

It's likely that this loop would continue, but mod_rewrite recognizes that you're redirecting to the same page and ignores your rewrite after this point.

这整个过程恰好就是为什么这两个条件...

This whole process happens to be why the two conditions...

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

...在 .htaccess mod_rewrite 规则集中非常常见,因为它们提供了一种简单的方法来确定 URL 是否已经被重写为预期的真实资源.您可以使用它们,也可以在将请求重写为 assets.php 时排除 index.php 重写:

...are so common in .htaccess mod_rewrite rulesets, given that they provide an easy way to determine if the URL has already been rewritten to the intended real resource. You could use them, or you can exclude the index.php rewrite when the request has been rewritten to assets.php:

RewriteCond %{REQUEST_URI} !^/assets.php
RewriteRule ^([a-zA-Z0-9_.-]+)$ index.php?url=$1&%{QUERY_STRING} [L]

这篇关于重写问题 - L(ast) 不被尊重?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 21:49