Regex 如何强制mod_重写跳过真实文件
我有一个应用程序,它通过Regex 如何强制mod_重写跳过真实文件,regex,apache,.htaccess,mod-rewrite,Regex,Apache,.htaccess,Mod Rewrite,我有一个应用程序,它通过index.php路由所有请求 以下是我的设置: 我在http://www.example.com/sample/ 在文件系统上,应用程序位于/home/chris/www/sample/ 应用程序的web可访问目录位于/home/chris/www/sample/app/web DocumentRoot设置为/home/chris/www /home/chris/www/sample/.htaccess配置如下: RewriteEngine on RewriteCon
index.php
路由所有请求
以下是我的设置:
http://www.example.com/sample/
/home/chris/www/sample/
/home/chris/www/sample/app/web
DocumentRoot
设置为/home/chris/www
/home/chris/www/sample/.htaccess
配置如下:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/sample/(.+)$
RewriteCond %{DOCUMENT_ROOT}/sample/app/web/%1 -f
RewriteRule ^/sample/(.*)$ %{DOCUMENT_ROOT}/sample/app/web/%1 [L]
RewriteRule ^(.+)$ index.php?ws_page=$1 [L,NC,QSA]
我已经尝试了多种配置,但还没有弄明白为什么我总是在调用“真实”文件时得到404
样本404:
`http://www.example.com/sample/_css/960/reset.css`
(我想将其重写为/home/chris/www/sample/app/web/_css/960/reset.css
)
编辑
我已经试过了
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !-l
它们不起作用,因为%{REQUEST_URI}前缀与这些文件的文件系统前缀不匹配
编辑2
为了澄清,我需要表格的要求
`http://www.example.com/sample/foo/bar`
要重写到文件系统对象/home/chris/www/sample/app/web/foo/bar
,但仅当该文件系统对象存在时
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
这两条规则将跳过实际存在的文件(-f)和目录(-d)。您的代码如下:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /sample
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+sample/(.+)\s [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond /home/chris/www/sample/app/web/%1 -f [NC]
RewriteRule ^ /sample/app/web/%1 [L]
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid symlink
RewriteCond %{REQUEST_FILENAME} !-l
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
任何人都可以向我解释为什么我的EOS锚(
$
)是重写规则不起作用的罪魁祸首
我最后说:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/sample/(.+)
RewriteCond %{DOCUMENT_ROOT}/sample/app/web/%1 -f
RewriteRule ^(.*)$ app/web/$1 [L,NC,QSA]
RewriteCond %{REQUEST_URI} !(^/sample/app/web)
RewriteRule ^(.+)$ index.php?ws_page=$1 [L,NC,QSA]
非常感谢所有帮助我诊断这一奇怪现象的人。阅读mod_rewrite文档《系统中的行为差异》时最大的麻烦之一(这是main和vhost配置apache在启动时读取的内容,以及每个目录上下文中的那些指令进程。有关详细信息,请参阅的每个目录重写小节 在
.htaccess
文件中使用重写引擎时,每个目录前缀(对于特定目录总是相同的)将自动删除以进行重写规则模式匹配,并自动添加到任何相关文件之后(不以斜杠或协议名开头)替换遇到规则集的结尾。有关将哪些前缀添加回相对子条件的详细信息,请参阅指令
后来
删除的前缀总是以斜杠结尾,这意味着匹配是针对一个从不具有前导斜杠的字符串进行的。因此,^/
的模式在每个目录上下文中从不匹配。您所做的是围绕此进行编码
顺便说一句,这就是为什么指定一个重写基总是比较安全的原因,因为引擎在没有这个的情况下会出错
顺便说一句,第二个引号可能是错误的,因为前缀add back发生在规则集执行的then处,并且如果您有一个成功的规则,该规则指向不同的相对分支(即目标以/
开头),但没有[L]
标志集,则引擎将使用一个前导的/
集执行任何后续规则。最令人困惑的是,我的一般建议是永远不要依赖于失败规则。始终在每个目录上下文中成功替换时强制立即进行内部或外部重定向,因为引擎中存在此错误和其他两个错误这个秋天,通过处理。我尝试的第一件事。另外,我想你是想在那里使用RewriteCond
。你是否有可能在css、js、图像等中使用相对路径?你也可以在这里复制/粘贴404错误日志文件。实际上,混合了。我一直在尝试一个css文件和一个js文件。一个是相对的,一个是绝对的。两个都是fai如果有帮助的话,这实际上会导致无限重定向循环(公平地说,这可能不完全是mod_rewrite所做的-我的应用程序中也有一些重定向逻辑)。首先,你应该用绝对路径替换所有相对路径。其次,我不理解404http://www.example.com/sample/_css/960/reset.css
自从您编写了我的所有资产(css、图像等)在app/web/
下。最后,我建议您在httpd.conf中启用RewriteLog并查看生成的输出。相对于.htaccess
文件,资产存在于文件系统上的app/web
中。但是,它们是通过web根/sample/
请求的。Chris,这是RTFM的一个例子。“删除的前缀总是以斜杠结尾,这意味着匹配发生在一个从来没有前导斜杠的字符串上。因此,^/
的模式在每个目录上下文中永远不匹配。”。"你可以去掉前导的/。你所做的就是围绕这个进行编码。哇…非常有启发性。谢谢!我不知道我怎么会这么久都没有意识到前缀在每个目录上下文中被删除。克里斯,在你没有Apache根访问权限的地方调试htaccess文件是一个真正的错误,因此。我还有一个VM whic正如我所描述的,由于这个原因,h镜像了我的主机提供商共享服务。很好的参考资料——我还没有找到那个帖子。