现有文件的 RewriteCond 文件存在检查失败

dec*_*eze 7 mod-rewrite apache-2.2

我对这个重写规则有一个奇怪的场景:

RewriteCond img/$2/$3/$4/$1 -f
RewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\.\w+)$ img/$2/$3/$4/$1 [L]
Run Code Online (Sandbox Code Playgroud)

目录结构为(简化):

var/
  images/
    ..
  www/
    .htaccess
    img -> /var/images
Run Code Online (Sandbox Code Playgroud)

换句话说,图像存储在 webroot 之外的通用数据存储区域中,并img通过符号链接链接到 webroot 的目录中。图像名称是散列。为提高效率,它们存储在三级深层目录层次结构中。例如:

0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg
Run Code Online (Sandbox Code Playgroud)

存储在

images/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg
Run Code Online (Sandbox Code Playgroud)

重写规则只是将文件名重写到嵌套目录结构中。

现在,奇怪的是它RewriteCond在我的本地系统上运行良好,但在测试服务器上却失败了。Apache 调试日志明确指出-f此条件的“模式不匹配”​​。如果我只是删除此条件,则重写规则可以正常工作并提供图像。

什么可能导致-f明显存在的文件失败?

FollowSymLinks被允许。通过 apt 安装的 Apache 版本 2.2.22-6ubuntu2 几乎没有修改。适用于 Apache 2.2.23 的本地安装(通过自制软件)。看不到应该导致这种情况的两个版本之间的任何重大变化


关于实际目录结构的一些可能更重要的细节:

$ ls -l /var/www/myapp/current
[snip] /var/www/myapp/current -> /var/www/myapp/releases/20130418090750

$ ls -la /var/www/myapp/current/webroot
[snip]
[snip] .htaccess
[snip] img -> /usr/local/var/myapp/images
Run Code Online (Sandbox Code Playgroud)

Apache webroot 配置为:

DocumentRoot /var/www/myapp/current/webroot
Run Code Online (Sandbox Code Playgroud)

如果我写RewriteCond为:

RewriteCond /usr/local/var/myapp/images/$2/$3/$4/$1 -f
Run Code Online (Sandbox Code Playgroud)

有用。如果可以避免的话,我宁愿不硬编码绝对路径。

Apache 可能会被几个级别的符号链接混淆吗?

小智 1

实际上,我从未见过一篇文章有​​关于RewriteCond从下面获取变量的教程。但是,您仍然可以尝试在.htaccess文件的顶部RewriteRule添加指令:RewriteBase

\n\n
RewriteBase /www/\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者这个,都尝试一下:

\n\n
RewriteBase /var/www/\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者您可以尝试下面这些指令集之一,但排除上面列出的任何RewriteBase指令:

\n\n
RewriteCond /www/img/$2/$3/$4/$1 -f\nRewriteRule ^www/img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\\.\\w+)$ /www/img/$2/$3/$4/$1 [L]\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者你甚至可以尝试一下:

\n\n
RewriteCond /var/www/img/$2/$3/$4/$1 -f\nRewriteRule ^var/www/img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28}\\.\\w+)$ /var/www/img/$2/$3/$4/$1 [L]\n
Run Code Online (Sandbox Code Playgroud)\n\n

我很抱歉复制您的重写条件和规则的格式,因为您说\xe2\x80\x9cit 适用于您的本地开发系统。\xe2\x80\x9d但这是我向您推荐的简单规则如果您只想将/$var1.$var2重写为/images/0a80/8e34/edaa/$var1.$var2,您甚至可以一一静态添加其他内容:

\n\n
RewriteRule ^([a-zA-Z0-9_-]+).([a-zA-Z]{3})$ /images/0a80/8e34/edaa/$var1.$var2\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,如果您想将/img/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg动态重写为/img/0a80/8e34/edaa/0a808e34edaaeeffd973e4138789a4957d6b6a26.jpg,条件是重新映射的动态 URL 是,您甚至可以尝试此操作一个文件:

\n\n
RewriteCond /img/$2/$3/$4/$1\\.$5 -f\nRewriteRule ^img/(([a-z0-9]{4})([a-z0-9]{4})([a-z0-9]{4})[a-z0-9]{28})\\.([a-z]{3})$ /img/$2/$3/$4/$1.$5\n
Run Code Online (Sandbox Code Playgroud)\n\n

请记住, “0a80”“8e34”“edaa”上的字符必须与 4 和字符完全相同。在“eeffd973e4138789a4957d6b6a26”中必须为28,在“jpg”中必须为3。我希望这会起作用,但我怀疑..

\n