Blog. Just Blog

Обработка недоступных картинок на сайте

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Обработка недоступных картинок на сайте
Обработка недоступных картинок на сайте

Одно из неприятных явлений в Интернете - это "битые" ссылки, в частности ссылки на картинки. Сайты могут закрываться, переезжать, менять свою структуру, это естественный процесс. Хуже, когда от этого страдает ваш сайт. Если на сайте всего несколько страниц, то "битые" картинки вы сможете легко отследить самостоятельно, а о некоторых могут сообщить ваши посетители. Но если страниц много, то в большинстве случаев "битые" картинки могут висеть незамеченными достаточно долго. На своем хостинге их, в принципе, можно отследить по появлению ссылок в логе ошибок 404 (страница не найдена), а если изображения находятся на другом сервере?

Я придумал способ, который позволяет автоматизировать процесс обнаружения "битых" картинок на сайте. Он основан на том, что при недоступности какого-либо внешнего объекта возникает ошибка, которая генерирует событие onerror. Перехватив и обработав это событие, можно уведомить администратора сайта о возникшей проблеме. Обработчик состоит из трех частей: первая часть выполняется в браузере посетителя сразу после загрузки страницы и устанавливает перехватчик на все картинки на странице.
  1. // Кроссбраузерная установка перехватчика ошибок на все картинки
  2. var obj document.getElementsByTagName('img');
  3. for(var 0;i<obj.length;i++) {
  4.   if (obj[i].addEventListener) {
  5.     obj[i].addEventListener('error'handle_errorfalse);
  6.   }
  7.   else {
  8.     obj[i].attachEvent('onerror'handle_error);
  9.   }
  10. }
Вторая часть получает управление при ошибке, и также выполняется в браузере пользователя. Ее задача заключается в том, чтобы заменить битую картинку на какую-нибудь дефолтную.
  1. // Обработчик битых картинок
  2. function handle_error(e) {
  3.   e window.event;
  4.   var imgElem e.target e.target e.srcElement;
  5.   imgElem.src='error_picture.php?src='+imgElem.src+'&page='+document.location.href;
  6. }
И, наконец, третья - серверная часть, выполненная в виде PHP-скрипта. Она получает и обрабатывает битую ссылку, делает запись в лог или отправляет уведомление администратору сайта, а затем возвращает дефолтное изображение.
  1. <?
  2. //--------------------------------------------------------------------
  3. // Серверный обработчик битых ссылок
  4. //--------------------------------------------------------------------
  5. // Прочитать дефолтную картинку с диска
  6. $f=@fopen('error.gif','r');
  7. Header('Content-type: image/gif');
  8. // Передать ее в браузер
  9. echo fread($f,filesize('error.gif'));
  10. fclose($f);
  11.  
  12. // Получить ссылку на страницу с битой ссылкой и саму битую ссылку
  13. $f=fopen('error.log','a+');
  14. $str  "Date: ".date("d.m.Y H:i:s")."\r\n";
  15. $str .= "Picture: ".$_GET['src']."\r\n";
  16. $str .= "URL: ".$_GET['page']."\r\n";
  17. $str .= "------------------\r\n";
  18. // Записать данные в лог-файл
  19. fwrite($f,$str);
  20. fclose($f);
  21. ?>
Как все это работает? После загрузки страницы каждой картинке добавляется обработчик события onerror. При возникновении ошибки (битая ссылка на картинку), управление передается обработчику ошибки. Он получает адрес картинки из тега img, адрес страницы, на которой произошло событие, а затем подменяет битую ссылку ссылкой на PHP-скрипт, передавая ему в качестве параметров адрес картинки и страницы. Скрипт на сервере сохраняет в лог полученную информацию об ошибке, читает файл с дефолтным изображением и отдает его в браузер вместо битой картинки. Пример работы можете посмотреть у меня на сайте.

Поделиться ссылкой ВКонтакте
Просмотров: 9058 | Комментариев: 11

Метки: JavaScript
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (06.11.2010 в 21:53):
Да, именно так.
Игорь (06.11.2010 в 21:48):
RewriteCond %{REQUEST_FILENAME} .*jpg$|.*gif$|.*png$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !vashsait.ru [NC]
RewriteCond %{HTTP_REFERER} !yandex.ru [NC]
RewriteCond %{HTTP_REFERER} !google. [NC]
RewriteCond %{HTTP_REFERER} !search?q=cache [NC]
RewriteRule (.*) error.gif

А error.gif это и есть та самая дефолтная картинка ?
ManHunter (06.11.2010 в 20:58):
Это делается через .htaccess
Игорь (06.11.2010 в 19:39):
Привет. А как реализовать, чтобы картинки отображались только на своем сайте, а на других сайтах эти картинки (скопипастенные) отображались ввиде Дефолтной картинки.
Infocatcher (03.06.2010 в 20:09):
С зацикливанием проще - можно проверять адрес картинки, вызвавшей событие error. Что-то вроде такого:
var newSrc = ...;
if(img.src != newSrc)
    img.src = newSrc;

Правда, лучше через что-нибудь навроде img.src.indexOf(newSrc) проверять, если newSrc - относительный (как в примере).

P.S. А мелкомягким давно пора по тому, что у них заместо головы, надавать:
var s = "89"; "0123456789".substr(-s.length) == s;
ManHunter (03.06.2010 в 08:01):
Поправил парсер, больше не должен жрать непечатные буквы.

А мне вот другое интересно: что получится, если будет недоступен скрипт-обработчик битой картинки (который .php)? Будет вечный цикл onerror?
Infocatcher (02.06.2010 в 18:55):
Ну, допустим, сервер с картинкой может лежать или еще что-нибудь вре

Ну вот, срезало все после символа ударения ( http://ru.wikipedia.org/wiki/%...%D1%83%D1%82 ). =/

Хех, речь забыл. :D Если оригинал восстановим - лучше вернуть его.

Ну, допустим, сервер с картинкой может лежать или еще что-нибудь врЕменное. Или вот зашел - понравилось - сохранил и только потом заметил, что в середине потерялась картинка. Так что вреда же не будет, а пригодиться вполне может.
Что, интересно, будет у посетителя с медленным каналом после загрузки картинки только до половины? Если всплывет событие load, то не логично - скорее уж error. Но тут хорошо бы поставить эксперимент.
ManHunter (01.06.2010 в 23:49):
Для посетителя какая разница, в каком виде ему будет показываться НЕДОСТУПНАЯ картинка? Это ж все задумано, чтобы автоматически и как можно быстрее уведомить админа, что у него что-то поломалось.
А мысль на счет глобального перехватчика ошибок я подумаю :)
Infocatcher (01.06.2010 в 23:34):
Хорошая идея. Разве что неплохо бы оставлять в удобном для пользователей виде ссылку на оригинал.

Кстати, достаточно только одного обработчика:
javascript: window.addEventListener("error", function(e) { alert(e.target.src); }, true); document.images[0].src = "notFound"; void 0;

В Firefox работает. =)
В IE, вроде бы, события не всплывают. А весь прочий зоопарк проверять лениво.
user (01.06.2010 в 14:41):
Мдя... всё гениальное просто...
64-ядерный процессор (29.05.2010 в 00:26):
Так можно отслеживать не только недоступность картинок, но и вообще всего. То есть полностью мониторить "работоспособность" страниц сайта ))

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0041 сек.) / Память: 4.5 Mb
Наверх