Часто при поисковой оптимизации сайта возникает задача избавиться от URL, кончающихся на ?, например, http://4xpro/profblog/?. С точки зрения поисковых систем такие адреса воспринимаются как дубли. На первый взгляд, это кажется простой задачей: нужно прописать в .htaccess правило для mod_rewrite. Но при попытке это сделать вас ждёт неприятный сюрприз: этот знак вопроса не входит ни в ту часть URL, которая проверяется по RewriteRule, ни в переменную %{QUERY_STRING}, которую можно проверить с помощью RewriteCond. К счастью, решение всё же есть: использовать %{THE_REQUEST}, куда Apache помещает полную строку HTTP-запроса. Тогда получаем вот такое условие:
RewriteCond %{THE_REQUEST} \?
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L,QSD]
Здесь первая строка проверяет на то, что знак вопроса вообще присутствует в запросе, вторая — на то, что QUERY_STRING пуста (то есть после знака вопроса ничего нет), и третья выполняет редирект на URL без этого знака (за это отвечает флаг QSD).
Ещё одним источником дублей является index.php. Если сделать редирект, прописав его напрямую в RewriteRule (что-то вроде RewriteRule ^/index.php$ https://%{HTTP_HOST}/ [R=301]), можем получить зацикливание. Поэтому нужно проверить, что он есть в запросе явно. Делается это с помощью %{REQUEST_URI}:
RewriteCond %{REQUEST_URI} ^/index.php$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L,QSA]

- Перово, Москва, Россия
- me@4xpro.ru
- XXXXPro
Новости сайта в Telegram
t.me/4x_proКомпьютерное
Избавляемся от знака вопроса в конце URL

Отслеживаем время запросов в Apache и NGinx

Я уже писал о том, как отслеживать медленные запросы с помощью MySQL. Но не всегда причина бывает в базе данных. Поэтому имеет смысл применять и другой способ — использовать логи Web-серверов. В современных версиях Apache и NGinx есть возможность выводить в лог время выполнения запроса с точностью до миллисекунд.
В NGinx это делается так: сначала объявляем формат лога с помощью директивы log_format и придумываем ему имя, например, logtimed. Возьмём за основу формат по умолчанию, и добавим к нему время выполнения и длину запроса. А потом объявим использование этого формата в директиве access_log:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
' $request_time $request_length';
access_log /var/log/nginx/access.log logtimed
Директива может использоваться на любом уровне (http, server, location), но в документации сказано, что следует использовать тот же, на котором прописана директива root.
В Apache требуется включить mod_log_config. Далее всё делается аналогично, только директивы называются LogFormat и CustomLog, а вывод времени запроса можно задать двумя способами — либо как %D (в микросекундах), либо как %msT (с версии 2.4.13) — в миллисекундах, либо как %T — в сеундах:
LogFormat "%h %l %u %t \"%r\" %>s %b %D" logtimed
CustomLog /var/log/apache2/access.log logtimed
Эти директивы можно использовать либо в глобальной конфигурации, либо на уровне VirtualHost.
Надеюсь, эта информация поможет выявить медленные запросы и сделать ваши сайты и сервисы быстрее.
Отладка правил для mod_rewrite

Наверное, каждый, кто когда-либо настраивал Apache, сталкивался с ситуацией, когда правила для mod_rewrite вида RewriteCond или RewriteRule не срабатывают. Поиск причин и отладка регулярных выражений может стать долгим и мучительным процессом, но есть несколько способов его упростить.
Способ 1, официальный. Включить сохранение отладочной информации через директивы в настройках. Для Apache 2.2 они выглядят так:
RewriteLog /path/to/log
RewriteLogLevel 5
Для Apache 2.4:
LogLevel warning rewrite:trace2
Вся отладочная информация о том, с какими регулярными выражениями совпал присланный URL, а с какими — нет, будет записываться в указанный файл. Данный способ имеет целый ряд недостатков: его нельзя включать через .htaccess, а можно только через основной файл настроек, на активно посещаемом сайте файл лога очень быстро растет, для его включения/выключения нужно перезапускать Apache.
Способ 2 — воспользоваться специальными сайтами, например, htaccess tester. Такие сайты позволяют ввести URL и содержимое правил .htaccess, а затем показывают, какие правила сработали, и как будет выглядеть URL после преобразования. Это весьма удобно, но не всегда позволяет учесть какие-то особенности конкретного сервера, например, провести проверку существования файла.
Способ 3, «хакерский». Как известно, в mod_rewrite можно задавать переменные среды через параметр E=. В них можно выводить, в том числе, и части сработавших регулярных выражений, обозначаемые как $1, $2 и $3. А уже эти переменные среды можно выдавать в расширенных HTTP-заголовках, названия которых начинаются с X-, например, X-Debug. Делается это так:
RewriteRule ^f/up/(.*)/(.*)\.htm$ - [E=DBG:$1]
Header set X-Debug: %{DBG}e env=DBG
Кроме того, так можно выводить REQUEST_FILENAME или REQUEST_URI (пишется так: Header set X-Debug: %{REQUEST_FILENAME}e) для того, чтобы посмотреть путь или URL, который получается после всех преобразований. Это бывает полезно, если после отработки правил mod_rewrite начинает возникать ошибка 404.
Примечание: для того, чтобы этот способ работал, должны быть включены mod_env и mod_headers.
Еще один совет — выполнять отладку не через броузер, а либо отправлять запросы через curl или wget, либо использовать специальные утилиты типа Postman. Это позволяет значительно быстрее отправлять повторные запросы после каждого изменения в .htaccess.
Как перейти на формат WebP с минимальными изменениями сайта

Некоторое время назад появился новый формат для графических изображений — WebP. Этот формат обладает рядом преимуществ по сравнению с JPEG: поддерживает как сжатие с потерями, так и сжатие без потерь, а также прозрачность изображений (альфа-канал), и во многих случаях сжимает изображения эффективнее (на моих сайтах — изображения в WebP получаются 30-35% меньше). Но к сожалению, полностью перейти на этот формат пока не так просто. Во-первых, сейчас его полноценно поддерживают только Web-броузеры, работающие на основе WebKit, а Firefox и IE/Edge — нет. Во-вторых, исправить на уже существующем сайте расширения всех файлов с .jpg на .webp может быть весьма трудоемкой задачей. Но недавно я нашел интересное решение, которое предложил Vincent Orback на Github: использовать подмену JPEG на WebP с помощью mod_rewrite. Для этого добавим в .htaccess такие строки: Читать далее…
Отслеживаем медленные запросы или Почему тормозит Web-сервер

Бывают ситуации, когда Web-сервер тормозит, медленно выдает страницы, а что именно является причиной, непонятно. Первое что приходит в голову — поставить в скриптах контрольные точки, в которых фиксировать время выполнения скриптов. Это может быть достаточно трудной задачей, а при большой нагрузке и вовсе привести к зависанию. Поэтому сначала лучше попробовать встроенные средства Apache и MySQL: mod_status и лог медленных запросов.