mod_rewrite麻烦

时间:2011-09-18 15:21:10

标签: apache .htaccess mod-rewrite

我正在尝试重写对存在的文件的请求,无论其扩展名如何,在该目录的公共目录中,以及控制器的其他所有内容。如果用户转到http://example.com/images/foo.gif并且它存在,则应该从%{DOCUMENT_ROOT} /public/images/foo.gif提供图像。如果它们转到http://example.com/foo/bar,并且它不存在,那么请求应该通过index.php进行路由。到目前为止我所拥有的是两个单独工作的块,但不是一起工作。当两者都放入.htaccess时,无论哪个是第一个.htaccess都能完美地工作,而底部的那个完全被忽略(当我尝试测试它时会给出404页面)。有人可以向我解释我做错了吗?

RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} -f
RewriteRule ^.*$ - [L]
RewriteRule ^.*$ index.php [L]

RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} !-f
RewriteRule ^.*$ - [L]
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/public/$1 [L]

1 个答案:

答案 0 :(得分:0)

看起来有些事情是错的。

看起来你的RewriteCond是倒退的。如果%{DOCUMENT_ROOT}/public/%{REQUEST_URI} 不存在<!em>(!-f),那么你想重写为index.php,但如果 存在(-f)则重写到/ public / $ 1。第二件事是RewriteRule ^.*$ - [L]实际上阻止了实际规则的应用,因为它以 [L] 结束并且在当前迭代中停止重写。

即使您删除^.*$ - [L]重写并翻转-f!-f,您也会遇到第二次重写问题:

RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} !-f
RewriteRule ^.*$ index.php [L]

RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} -f
RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/public/$1 [L]

当您尝试访问http://example.com/foo/bar时会发生这种情况:

  1. %{DOCUMENT_ROOT} / public // foo / bar不存在,! - f condition met
  2. foo / bar被重写为index.php,[L],end rewrite
  3. 请求被内部重定向到index.php
  4. 使用新的URI(index.php)重新应用所有规则
  5. %{DOCUMENT_ROOT} /public/index.php存在,! - f条件失败
  6. %{DOCUMENT_ROOT} /public/index.php存在,-f condition met
  7. index.php被重写为%{DOCUMENT_ROOT} /public/index.php
  8. INTERNAL重定向,所有规则都重新应用于新URI(/public/index.php)
  9. %{DOCUMENT_ROOT} /public//public/index.php不存在,! - f condition met
  10. public / index.php被重写为index.php
  11. 返回3.内部循环
  12. 当您尝试访问http://example.com/images/foo.gif时会发生类似情况,实际上,您需要让其他规则停止重写第二次。所以你需要添加第二组条件:

    RewriteCond %{REQUEST_URI} !^/public/
    RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} !-f
    RewriteRule ^.*$ index.php [L]
    
    RewriteCond %{REQUEST_URI} !/index.php
    RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} -f
    RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/public/$1 [L]