Set web server handle 404 errors for some file typ

2019-07-04 02:05发布

问题:

It's my first question in this great community (please tell me if I'm doing anything wrong). I learned a lot of from your answers in the past 5-6 years and now I have very specific question, which I couldn't find on the Internet (is this possible?)...

The goal is to set custom ErrorDocument 404, that handles not existing chosen static files like: /notfound.jpg and in a subdirectory (for any directory): /dir/notfound.jpg, for sites running under Wordpress with pretty permalinks enabled. It will avoid high load on the server when some chosen static files are missing or linked incorrectly!

I'm using a slightly modified code from the W3 Total cache plugin in my .htaccess file:

ErrorDocument 404 /_code_404.html

# BEGIN (modified) W3TC Skip 404 error handling by WordPress for static files
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !(robots\.txt|sitemap\.xml(\.gz)?)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} \.(css|js|bmp|gif|ico|jpg|jpeg|jpe|png|swf)$ [NC]
RewriteRule .* - [L]
</IfModule>
# END (modified) W3TC Skip 404 error handling by WordPress for static files

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

I'm trying it on 2 different servers with Cpanel, on shared plans, both have Wordpress with pretty permalinks and the result is the same:

  1. Works just as expected for requests like http://mydomain.com/notfound.jpg

  2. Doesn't work for not found file in a subdirectory like this http://mydomain.com/dir/notfound.jpg. In this case the WP handles the request and shows 404 page, which I want to avoid for certain file types, i.e. for static files like: css, js, jpg and a few more...

Any answers and comments are welcome, thanks! I can try any suggestions you may have (even untested).

EDIT 1: A note to each other trying to get it to work (see accepted answer + the note below):

It seems you must (or depend on server config) set custom error 404 page, otherwise the rewrite which excludes some chosen file types will not work and as a result the WP will process the request! (it seems not much people note this, or it could be related to the server config)

I realized that, because I was trying the proposed solution even before I write this question, but without the "ErrorDocument 404" line and it didn't work.

EDIT 2: Tests and another note:

  1. During the tests I tested the URLs with query string: /12345.css?v=5 and /dir4/12345.css?v=3&t=66 [It works fine, because REQUEST_URI excludes query string!]

  2. Very important thing to note is that the server usually should return HTTP code 404 for missing files (otherwise search engines can hurt your rankings). If you set the full domain name in: ErrorDocument 404 http: //mydomain.com/_code_404.html, then the the "client will not receive the original error status code, but instead will receive a redirect status code". (reference - httpd.apache.org/docs/2.0/mod/core.html#errordocument)

回答1:

Can you try this:

ErrorDocument 404 /_code_404.html

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_URI} !(robots\.txt|sitemap\.xml(\.gz)?)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.(css|js|bmp|gif|ico|jpe?g|jpe|png|swf)$ [NC]
RewriteRule .* - [L]

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>