问题描述
|
我的网站目前的结构方式,实际的网站位于其自己的单独文件夹中。这是我的意思:
/projects
/files
/pictures
/tools
/school
/~webroot
.htaccess
这使文件系统更易于管理和导航。一个简单的方法来使用此方法,而不用让所有人都导航到ѭ1,并且仍然允许他们访问文件(例如ѭ2),是使用我在下面编写的htaccess
来检查真实根目录和〜webroot目录中的文件。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /~webroot/$1 [NC,QSA]
RewriteRule ^/?$ /~webroot/index.PHP [L,QSA]
但是,如果该文件在任何地方(根目录或〜webroot)都不存在,则会引发HTTP 500错误而不是HTTP404。为了显示404错误页面,我必须改用以下行:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/~webroot/$0 !-F
RewriteRule ^(.*)$ /404.shtml [B,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^/~webroot
RewriteRule ^(.*)$ /~webroot/$1 [NC,QSA]
这一切都非常混乱,这只是一个技巧,实际上并没有抛出HTTP 404,这使404无法使用我的统计应用程序进行记录。有没有一种方法:检查根目录中是否存在文件,如果不存在,则检查〜webroot中是否存在文件,如果不存在,则抛出真实的HTTP 404错误?
我也确实正确定义了所有的ErrorDocument
\。
解决方法
我知道这是前一阵子,但我想插话。对于要打到404的重写规则,我总是使用以下命令:
RewriteRule ^(.*)$ - [R=404,L]
我不确定是否正确,但是对我有用。我很确定它应该始终与\“ L \”一起使用,以防止进一步重写。
顺便说一句,“ B”标志的作用是什么?我只知道apache mod_rewrite页面上列出的内容,所以我对它的含义不了解。
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
编辑:啊,我的问题是我看旧版本的文档。谢谢你,Swivelgames。如果您没有指出(需要更新我的书签),我可能甚至不会知道我正在查看旧文档。
http://httpd.apache.org/docs/2.3/rewrite/flags.html#flag_b
, 如果您可以将404页面设为PHP文件,则可以在任何输出之前添加此文件以获得真实的404:
<?php header(\"HTTP/1.1 404 Not Found\"); ?>
这将导致PHP触发\'real \'404(从浏览器的角度来看),该404将被传递回浏览器。如果您不确定统计信息包是否在服务器内部,则我不确定这种方法是否有效。
我能想到的唯一其他解决方案是重定向到不存在的文件:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/non-existent-404-generator
RewriteCond %{DOCUMENT_ROOT}/~webroot/$0 !-F
RewriteRule ^(.*)$ /non-existent-404-generator [B,L]