开发者

.htaccess Check for file in two locations, otherwise throw 404

开发者 https://www.devze.com 2023-03-10 00:54 出处:网络
The way my site is currently structured, the actual site is in its own separate folder. Here\'s what I mean:

The way my site is currently structured, the actual site is in its own separate folder. Here's what I mean:

 /projects
 /files
 /pictures
 /tools
 /school
 /~webroot
 .htaccess

This makes the file-system much easier to manage and navigate. An easy way to utilize this, without having everyone navigate to http://domain.com/~webroot/, an开发者_JS百科d still allow them to access files and such like http://domain.com/projects/, is to use the htaccess I wrote below to check for files in both the real root, and ~webroot directories.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /~webroot/$1 [NC,QSA]
RewriteRule ^/?$ /~webroot/index.php [L,QSA]

However, if the file doesn't exist anywhere (root or ~webroot), an HTTP 500 error is thrown instead of an HTTP 404. In order to display my 404 error page, I have to instead use these lines:

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]
RewriteRule ^/?$ /~webroot/index.php [L,QSA]

This is all quite messy, and it's only a trick and doesn't actually throw an HTTP 404, which keeps 404s from being documented using my statistics application. Is there a way to: Check if file exists in root, if not check if file exists in ~webroot, if not throw real HTTP 404 error?

I do also have all my ErrorDocument's defined properly.


I know this was a while ago, but wanted to chime in. For a rewrite rule to hit a 404, I always use this:

RewriteRule ^(.*)$ - [R=404,L]

I'm not sure if it's correct, but it works for me. I'm pretty sure it should always be with "L" to prevent further rewriting.

BTW, what is the "B" flag for? I only know the ones listed on the apache mod_rewrite page, so I'm lost on it's meaning.

http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html

EDIT: ah, my problem is I look at older version docs. Thank you, Swivelgames. I probably would have never even known I was looking at the older docs if you hadn't pointed that out (need to update my bookmarks).

http://httpd.apache.org/docs/2.3/rewrite/flags.html#flag_b


If you can make your 404 page a PHP file, you can add this before any output to get real 404's:

<?php header("HTTP/1.1 404 Not Found"); ?>

This will cause PHP to trigger a 'real' 404 (from the browsers point of view) which gets passed back to the browser. If your statistics package is internal to your server this approach may or may not work, I'm not sure.

The only other solution I can think of is to redirect to a non-existent file:

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]
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号