Назад | Перейти на главную страницу

Почему этот флаг -f возвращал истину?

Я недавно настроил перезапись для обслуживания .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.

Некоторые другие примечания:

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-файлы постоянно кэшируются браузером, поэтому позже могут возникнуть проблемы с кешированием. (Фактически, это может объяснить "прерывистое" поведение, когда запрос попадает в кеш браузера.)