404 заглушка для неіснуючих файлів

Почну з того, що цей пост, по суті, не несе будь-якої практичної користі для сайтів, які вже “встановлені” на сервер і повністю готові.

Роблячи якось «один сайт» я скопіював його на локалку (все окрім медіафайлів), а на сайті було багато картинок: щонайменше дві до запису плюс галереї. Виходило, що ні сторінка, то мінімум 2-3 картинки. Для того щоб працювати над сайтом картинки мені не потрібні, тому їх я з сервера не брав. Таким чином, при роботі на локалці на кожній сторінці у мене було мінімум 2 биті посилання на картинки, а то й 20.

Я помітив, що чим більше картинок на сторінці, тим довше вантажиться сторінка до 10 секунд. Це стало дратувати і довелося розібратися через таке неподобство. Причина виявилася в тому, що кожне бите посилання на картинку «приховано» генерувало 404 сторінку . Як приклад, можете спробувати вписати посилання типу: http://вашдомен/kartinka.jpg і ви отримаєте сторінку з помилкою, сторінку з усім вмістом сайту, з сайдбаром(и) та іншим…


Закриваємо непотрібні 404 сторінки

Виходить, щоб згенерувати сторінку з одним битим посиланням на файл, WordPress генерує дві сторінки: саму сторінку та сторінку з помилкою 404. Якщо на сторінці 2 биті посилання, то будуть створені 3 сторінки і т.д.

Звичайно, на робочому сайті битих посилань зазвичай немає, тому й проблеми такої немає, але на локалці не вантажити сторінку 404, якщо це файл може знадобитися. Втім, це може стати в нагоді і на робочому сайті див. нижче .


Варіант на .htaccess (рекомендую)

Цю проблему можна вирішити, додавши наступний код у файл functions.php і скинути правила ЧПУ :

# Додамо умови в .htaccess, які будуть видавати 404 відповідь сервера для неіснуючих файлів.
# Примітка: щоб код почав працювати, потрібно скинути правила перезапису (ЧПУ).
if( is_admin() ){

	add_filter( 'mod_rewrite_rules', 'block_nonexistent_files');
	function block_nonexistent_files( $rules ) {

		$add_rules = '
		# 404 для неіснуючих файлів.
		<IfModule mod_rewrite.c>
		RewriteEngine On
		RewriteBase /
		RewriteRule ^index.php$ - [L]
		RewriteCond %{REQUEST_FILENAME} !-f
		RewriteCond %{REQUEST_URI} !^/robots.txt$
		RewriteCond %{REQUEST_URI} .(php|s?htm|shtml|css|js|yml|swp|txt|jpe?g|png|gif|ico|pdf)(.*)?$
		RewriteRule. - [R=404,L]
		</IfModule>
		';

		$ add_rules = trim ($ add_rules);
		$add_rules = preg_replace( '/^t+/m', '', $add_rules );

		return "n$add_rulesnn" . $ rules;
	}
}

Щоб переконатися, що все працює, пишемо в браузер http://мой-домен/kartinka.jpg і бачимо 404 відповідь:

Що робить код?

Як тільки запитується файл (сторінка, що містить в кінці посилання .jpg , .gif , .png , .zip …), він перевіряється на фізичне існування, якщо його немає, робота скрипта обривається зі статусом 404 і до PHP, а значить і WordPress справа взагалі не доходить. Така заглушка генерується за частки секунди.

Задати шаблон 404 сторінці в цьому випадку можна через директиву ErrorDocument 404 /404.htmlта створення файлу 404.html у корені сайту.


Варіант на php (не рекомендую)

Код потрібно вставити на початок файлу index.php в кореневої директорії сайту, там де wp-config.php .

// Перевірка на тип помилки 404, якщо файл не генерувати сторінку,
// а просто писати про помилку
$URIreq = $_SERVER['REQUEST_URI'];
if ( preg_match('/.(jpg|jpeg|gif|png|zip)(?.+)?$/', $URIreq ) ){

	$PathToFileFromRoot = $_SERVER['DOCUMENT_ROOT'].$URIreq;
	$PathToFileFromRoot = str_replace( '//', '/', $PathToFileFromRoot );
	if ( !file_exists($PathToFileFromRoot) ){
		echo "<div style='margin:100px 10% 0 10%; padding:20px; text-align:center; border:1px solid #42A6FF; background:#DEF0FF; white-space:nowrap;'>
		<b>File not found:</b> $URIreq<br>
		<b>From Page:</b> <a href='{$_SERVER["HTTP_REFERER"]}'>{$_SERVER["HTTP_REFERER"]}</a><br>
		<div style='font-size:25px; padding-top:30px;'>Go to WebSite: <a href='http://{$_SERVER['HTTP_HOST']}'>http://{$_SERVER['HTTP_HOST']}</a>< /div>
		</div>";
		exit();
	}
}


Увага, вже для робочих сайтів!

Такому ж ефекту піддаються:

  1. Біті посилання на неіснуючі файли: картинки, що викликаються з css стилів і посилання на css, js та інші файли.
  2. Неіснуючі файли, до яких часто звертаються різні роботи-складачі, наприклад example.com/absd.php.
  3. Ваші віддалені зображення, які були скопійовані та використовуються на інших сайтах.

Тому якщо відчуваєте, що ваша сторінка вантажиться підозріло довго, перевірте всі посилання зі сторінки. Я так знаходив кілька битих посилань і не раз. Для прикладу візьмемо ось цей сайт: wordpressinside.ru , який можливо вам відомий, тут, на знижку, я знайшов як мінімум 2 биті посилання, ось вони (були до написання цієї статті smile):

  1. http://wordpressinside.ru/wp-content/plugins/simple-counters/js/sc.js.php
  2. http://wordpressinside.ru/wp-content/plugins/simple-counters/js/jquery.qtip.js
    Ці посилання вшиті в шаблон і при генерації будь-якої сторінки, паралельно генерується 2 сторінки 404. Думаю не складно уявити наскільки довше генерується сторінка, про зайві, абсолютно непотрібні навантаження на сервер я вже й не кажу…

Для вирішення проблеми можна просто видалити биті посилання – вони просто не потрібні.

Залишити коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *