Как пропустить обработку 404 в WordPress и перенаправить все 404 ошибки статических файлов на 404.html?
Как пропустить обработку 404 в WordPress и перенаправить все 404 ошибки статических файлов на 404.html?
Я читал, и похоже, это невозможно при использовании постоянных ссылок (permalinks)?
Цель состоит в том, чтобы уменьшить нагрузку на сервер при 404 ошибках, не загружая PHP.

.htaccess пропускает обработку ошибки 404 в WordPress для статических файлов.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(robots\.txt|sitemap\.xml(\.gz)?)
RewriteCond %{REQUEST_FILENAME} \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$ [NC]
RewriteRule .* - [L]
</IfModule>
Примечание: Эти правила были сгенерированы плагином W3 Total Cache*
Nginx пропускает обработку 404 в WordPress для статических файлов.
if (-f $request_filename) {
break;
}
if (-d $request_filename) {
break;
}
if ($request_uri ~ "(robots\.txt|sitemap\.xml(\.gz)?)") {
break;
}
if ($request_uri ~* \.(css|js|html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$) {
return 404;
}

Возможно, простое решение. Используйте условный тег is_404()
и создайте перенаправление на ваш статический файл; добавьте код в файл header.php
или index.php
темы.
Вот пример.
if ( is_404() ) {
wp_redirect( 'static.htm' );
exit;
}
Ссылки

принятие решений всё ещё происходит в PHP, а не на уровне htaccess. Цель - полностью пропустить загрузку PHP для ошибок 404.

@freethinker: верно, только через php; способ через htaccess быстрее, но, возможно, не так удобен в управлении в WordPress

Дополняя сказанное Chris_O... Я бы установил W3 Total Cache и использовал настройки этого плагина, чтобы не кэшировать статические файлы. Сам плагин очень полезен и обязателен для ускорения вашего сайта, особенно с последним обновлением.
Также рекомендую ознакомиться с Созданием страницы ошибки 404 на WordPress, чтобы узнать, как обрабатывать 404 для статических файлов, 403 (запрещено) и т.д. Это полезный материал.

Я не уверен, что это возможно. Если посмотреть на код .htaccess, который создает WordPress при включении постоянных ссылок, там по сути говорится: "Если файл/директория не найдены, перенаправь запрос на index.php". Это включает в себя все реальные 404-запросы. Если не создавать список всех динамически генерируемых публичных ресурсов, которые знает WordPress, и напрямую не вставлять их в .htaccess, вам все равно придется загружать PHP для обработки 404-ошибок.

Мне понравилась идея Chris_O, но я создал свою версию, которая более безопасна.
Я просто добавил папки в исключения, так что если запрос начинается с этих строк - это точно не валидный постоянный URL. Большинство таких запросов поступает от ботов, которые пытаются проверить содержимое этих папок на наличие уязвимостей. Они будут эффективно отфильтрованы, и при необходимости вы можете отображать небольшую статическую страницу 404.
Остальные запросы по-прежнему будут обрабатываться WordPress, и если кто-то введет неправильный адрес, будет показано дружелюбное сообщение "Не найдено" в рамках вашего шаблона. Решение Chris_O работает только для запросов, которые выглядят как расширения файлов, в противном случае они также будут обрабатываться WordPress.
Для большей надежности вы можете извлечь ваш raw access файл и поискать ошибки 404. Если вы заметите много запросов, начинающихся с определенных строк, их также можно включить в этот фильтр:
#добавление собственного обработчика
ErrorDocument 404 /404/index.html
<IfModule mod_rewrite.c>
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !^/(404|cgi-bin|wp-admin|wp-content|wp-includes)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

У меня на сайте установлено несколько CMS, поэтому я использую что-то вроде этого, чтобы использовать одну и ту же страницу ошибки 404 для всех CMS. Я использую эту конфигурацию для Nginx+FastCGI, и она работает отлично:
server {
...
error_page 404 /404.html; #включить кастомную страницу 404 ошибки
location ~ /\.ht {
deny all; #запретить доступ к htaccess
}
location ~ [^/]\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_intercept_errors on; #отключить перехват PHP 404 ошибок
}
location /wordpress/ {
try_files $uri $uri/ /wordpress/index.php?$args;
}
}
Я использую эту конфигурацию вместе с этим в php.ini:
cgi.fix_pathinfo = 1
WordPress установлен вот так: http://example.com/wordpress/. Файл 404.html находится в корне сайта http://example.com/.
P.S. Не забывайте, что после внесения изменений в файлы php.ini или nginx.conf необходимо перезапустить службы PHP и Nginx, чтобы изменения вступили в силу.

Привет, Mazhar, не мог бы ты опубликовать полный ответ, а не просто ссылку на свой сайт. Если эта ссылка перестанет работать, твой ответ станет практически бесполезным! Спасибо!
