【问题标题】:mod_rewrite help when .htaccess is located in subdirectory.htaccess 位于子目录中时的 mod_rewrite 帮助
【发布时间】:2014-09-07 14:11:43
【问题描述】:

我有一个简单的重写规则来检查请求文件的 *.gz 版本是否存在,如果存在则将该文件返回到浏览器(它基于这种提供压缩 CSS 和 JS 的技术:https://blog.jcoglan.com/2007/05/02/compress-javascript-and-css-without-touching-your-application-code/)。

假设我的 CSS 和 JS 位于我网站的 /cache 子目录中,例如:

http://domain.com/cache/app.css
http://domain.com/cache/app.css.gz
http://domain.com/cache/app.js
http://domain.com/cache/app.js.gz

当以下指令放置在 webroot 的 .htaccess 文件中时,一切都会按预期进行:

AddEncoding gzip .gz
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]

不过,我更愿意将这些规则放在该 /cache 目录中的单独 .htaccess 文件中。但按原样粘贴,这些规则不再起作用。据我所知,最后一个 RewriteCond 失败了,例如检查请求的文件名是否存在的条件。

我尝试添加RewriteBase /cache/,但这似乎不起作用。我已经删除了我的 webroot .htaccess,以防那里有另一个冲突的指令。我也尝试将 RewriteRule 更改为:

RewriteRule ^(.*)$ /cache/$1.gz [QSA,L]

虽然我认为这最终可能是正确的,但它仍然不起作用 - 就像我说的那样,因为据我所知是 RewriteCond 失败了。

所以我被难住了!有什么帮助吗?

【问题讨论】:

  • 您检查过 Apache 日志吗?它实际上尝试提供哪些文件?

标签: regex apache .htaccess mod-rewrite


【解决方案1】:

以下规则应该从/cache/.htaccess 开始工作:

AddEncoding gzip .gz
RewriteEngine On

# Determine the RewriteBase automatically/dynamically
RewriteCond $0#%{REQUEST_URI} ^([^#]*)#(.*)\1$
RewriteRule ^.*$ - [E=BASE:%2]

RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{HTTP_USER_AGENT} !Safari
RewriteCond %{DOCUMENT_ROOT}%{ENV:BASE}/$1\.gz -f [NC]
RewriteRule ^(.+?)/?$ $1.gz [L]

【讨论】:

  • %{DOCUMENT_ROOT}/cache/$1\.gz中的$1从何而来?
  • $1 来自RewriteRule,因为mod_rewrite 首先处理RewriteRule
  • 非常感谢,这就是诀窍!然而,似乎 RewriteBase 似乎不是必需的——事实上,当我删除该指令时,一切仍然有效。你能解释一下最后一个 RewriteRule,特别是 /?在比赛的第一部分?
  • Last RewriteRule 实际上使用.+? 模式捕获除了最后一个斜杠之外的所有内容,还请注意,最后一个尾随斜杠也使用/?$ 成为可选的。是的,可以删除 rewritebase 行。
  • 谢谢,这是有道理的——如果你不介意最后一个问题,有没有办法设置它,以便“缓存”可以是任何东西(并且可以是任何深度)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
相关资源
最近更新 更多