Не поставил favicon на сайте — получи двойной трафик от Chrome

в 13:59, , рубрики: Apache, favicon.ico, Google Chrome, htaccess, mod_rewrite, mysql, php, Разработка веб-сайтов

Впервые за пять лет разработки интернет-сайтов я столкнулся с весьма неожиданной проблемой, стоившей мне многих часов поиска, нервов и волос на голове. Внезапно я обнаружил, что на новом сайте, который у меня сейчас в разработке на локалхосте, дублируются INSERT запросы к БД. Отправляю один комментарий через форму, а в базу вставляются два. Если вы не знаете, как связана эта проблема с Chrome, favicon.ico и ModRewrite, то добро пожаловать под кат.

Нет, это не в глазах двоится

Разумеется, первое что пришло в голову — где-то в скрипте «двоится» запрос к базе данных. Например, такая «школьная ошибка»:

$query = "INSERT INTO table VALUES(...)";
$result = mysqli->query($query);
if ($result = mysqli->query($query)) {
...
}

Проверяю сто тысяч раз — нет. С кодом все в порядке. Значит браузер по какой-то причине отправляет данные дважды. Генерирую простенький тестовый скрипт с инкрементом сессионной переменной и — да! Вместо увеличения на единицу браузер упорно показывает увеличение переменной на два. Пробую вместо Хрома Сафари — нет такой проблемы. Далее идут поиски некорректно работающих яваскриптов, расширений для браузера, но все безрезультатно. Поиск по интернету давал схожие советы. Многие программисты в аналогичной ситуации вводили проверку на уникальность и отсекали дублирующиеся посты. Но баг то это решение не устраняет и я решил не останавливаться и найти причину такого поведения.

Наконец, причина была найдена. И так как решение нашел с трудом, на англоязычной девелоперской ветке, хочу поделиться им здесь. Все просто — виновника два: Google Chrome (и производные от него браузеры) и mod_rewrite в Apache.

Суть проблемы

Все просто. Особенность браузеров, построенных на платформе Crome в том, что они ищут файл favicon.ico для каждого сайта. И если его нет, то они все равно будут упорно его искать. При каждом обновлении страницы, отдельным запросом к серверу. А большинство .htaccess файлов в Apache имеют в себе строчки:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php

Руководствуясь этим правилом, получая запрос от браузера к несуществующему favicon.ico Apache послушно перенаправит его к файлу index.php и скрипт отработает дважды. Конечно, в большинстве случаев полноценные веб-приложения имеют проверку на уникальность и не пропускают повторяющиеся запросы. А сайты в большинстве случаев имеют файл favicon.ico. Но все же раз существует такая проблема, значит можно описать методы решения.

Варианты решения

Решение первое, самое простое: заведите на сайте favicon.ico. Chrome найдет его и успокоится.
Решение второе — немного изменить файл .htaccess на сервере. У меня блок правил mod_rewrite для всех проектов теперь будет выглядеть так:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
# Next line is to solve the Chrome and favicon.ico file issue.
# Without it browser sends two requests to script.
RewriteCond %{REQUEST_FILENAME} !favicon.ico
# RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Не поставил favicon? Получи двойной трафик от Chrome

Если вдуматься, то утверждение справедливо, ведь вместо того, чтобы отдать «статику», сервер будет запускать веб-приложение, которое в лучшем случае вернёт в браузер вместо иконки динамически сгенерированную 404 страницу. А в худшем — отработает полностью запуск главной страницы сайта. Получается, что не установив иконку на сайте (например, на одном популярном блоговом движке), разработчик вдвое увеличивает нагрузку на сервер от пользователей Google Chrome.

Вот, собственно и все. Надеюсь эта информация кому-то пригодится и сэкономит время.

Автор: IlyaMoiseev

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js