Я недавно настроил перезапись для обслуживания .webp
файлы вместо .jpg
файлы по возможности. Казалось, что он работает правильно, пока сегодня мы не заметили, что недавно загруженный .jpg
изображение возвращало 404
хотя изображение присутствовало. Я проверил и обнаружил, что сервер переписывает .jpg
URL на .webp
, а затем получить 404
поскольку .webp
еще не было создано.
Затем я переместил правило из vhost_ssl.conf в .htaccess и немного повозился, пока не нашел что-то, что работает, а затем переместил это решение обратно в vhost_ssl.conf. Но я до сих пор не понимаю, почему оригинальная перезапись иногда терпела неудачу. Может ли кто-нибудь рассмотреть и пролить свет на эту тему?
Оригинальная перезапись:
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
Окончательная переработка:
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_URI} (.+)\.(?:jpe?g|png)$
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
RewriteRule .* %1.webp [NC,T=image/webp,E=webp,L]
Единственная реальная разница между этими двумя методами заключается в том, что в новом методе я проверяю, соответствует ли URI запроса jpeg / png перед условием перезаписи, которое проверяет, существует ли файл. Я думаю, что новый метод менее эффективен, поскольку правило перезаписи соответствует всему, но по крайней мере условие выше фильтрует его, и он находится в vhost_ssl.conf, который лучше, чем .htaccess.
Некоторые другие примечания:
RewriteCond %{DOCUMENT_ROOT}/%1.webp_asdfasdfasf -f
просто чтобы убедиться, что он действительно потерпит неудачу, и это произошло. Таким образом, он знал, что полностью поддельного файла не существует, но все же считал, что файл .webp действительно существует.tl; dr
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
Так должно быть $1
не %1
в RewriteCond
TestString. Хотя непонятно, почему это поведение должно было измениться только недавно (а может, и нет?).
RewriteCond %{HTTP_ACCEPT} image/webp RewriteCond %{DOCUMENT_ROOT}/%1.webp -f RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
Это должно никогда работали, если у вас не было файла с именем ".webp
"(без базовое имя, начиная с точки) в корне документа. Если бы вы это сделали, то это было бы всегда переписать URL-адрес jpeg / png на <whatever>.webp
независимо от того, существовал он или нет.
Итак, похоже, у вас есть файл с именем .webp
(без базового имени) в корне документа? (И / или вы видите кешированное перенаправление для некоторых запросов? См. Ниже ...)
В %1
обратная ссылка во 2-м RewriteCond
TestString должно быть $1
не %1
. %1
это обратная ссылка на первую захваченную группу в последнем совпавшем CondPattern - которых нет, так что %1
является всегда пусто. Итак, это будет всегда проверить существование /path/to/document-root/.webp
. $1
с другой стороны, это обратная ссылка на первую захваченную группу в RewriteRule
шаблон, т.е. путь / базовое имя файловой системы, исключая расширение файла.
Вы использовали $1
в RewriteRule
замена - вы должны были использовать то же самое в предыдущем состояние.
Обратите внимание, что если эти директивы находятся в контексте виртуального хоста, вам следует либо ... удалить косую черту в RewriteCond
TestString, например:
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}$1.webp -f
RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
ИЛИ исключите косую черту в RewriteRule
захваченная группа. Например:
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
RewriteRule ^/(.+)\.(?:jpe?g|png)$ /$1.webp [NC,T=image/webp,E=webp,L]
В противном случае вы получите двойную косую черту в TestString что ОС должна будет решить.
RewriteCond %{HTTP_ACCEPT} image/webp RewriteCond %{REQUEST_URI} (.+)\.(?:jpe?g|png)$ RewriteCond %{DOCUMENT_ROOT}/%1.webp -f RewriteRule .* %1.webp [NC,T=image/webp,E=webp,L]
Это дает то же самое, что просто использовать $1
в исходном блоке правил (как упоминалось выше). Любопытно, что вы изменили обратную ссылку в замена к %1
, но знал, что нужно оставить обратную ссылку в условии без изменений (или это было просто пропущено)?
Во время тестирования я изменил исходную перезапись на редирект 301 ...
Всегда проверяйте с 302 (временными) перенаправлениями. 301-файлы постоянно кэшируются браузером, поэтому позже могут возникнуть проблемы с кешированием. (Фактически, это может объяснить "прерывистое" поведение, когда запрос попадает в кеш браузера.)