REQUEST_URI не соответствует явному пути и имени файла - PullRequest
1 голос
/ 31 мая 2019

Действительно озадачен, потому что форма и синтаксис кажутся хорошими.

RewriteCond для REQUEST_URI не соответствует явному пути и имени файла. Когда он изолирован, RewriteCond для REQUEST_FILENAME отлично подходит. Я проверил с помощью phpinfo (), что REQUEST_URI содержит начальную косую черту, и также проверил без передней косой черты.

Цель состоит в том, чтобы узнать, что запрос для этого файла и, если он не существует, бросить 410.

RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]

Я не хочу опускать первый Cond, потому что я хочу сделать это только для нескольких файлов, похожих на этот.

ОБНОВЛЕНИЕ I

пытается пройти окончательный тест. Тестовая установка:

  • testmee.txt не существует
  • запрос для testmee.txt в корне
  • подтвердил соответствие request_uri, перенаправив на Google
  • не может получить 410 при использовании только первого Cond
  • (при использовании только первого Cond сервер обслуживает 404, а не 410)
  • (используя оба Conds, сервер обслуживает 404, а не 410)
  • МОЖЕТ получить 410 при использовании только второго Cond
RewriteCond %{REQUEST_URI} ^/testmee\.txt$
#RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]

против

#RewriteCond %{REQUEST_URI} ^/testmee\.txt$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]

ОБНОВЛЕНИЕ II

Ответ для MrWhite:

тьфу, тот же симптом. Возможно, придется жить с роботом Google, нажимающим 404 вместо желаемых 410 для устаревших css / js. Наверное, в конце концов, не важно.

Благодарим вас за перенаправление теста request_uri. В этих тестах все работает нормально. Имена страниц и т. Д. Возвращаются, как и ожидалось, в URL-адресе var = rewrite.

На данный момент, я думаю, что это должна быть некоторая внутренняя обработка 404-х, связанных с расширениями типов файлов. Смотрите подсказку ниже. У меня есть программное обеспечение для корзины покупок Prestashop, и оно должно использовать 404 для типов файлов.

Это перенаправит на Google (для подтверждения соответствия шаблону):

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ http://www.google.com/ [L]
(L flag is needed or else other Rules further down will interfere.)

Это будет продолжать возвращать 404 вместо 410:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.txt$ - [NC,R=410]

И в качестве контрольного теста это вернет 410:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ - [NC,R=410]

Если тип файла css в приведенном выше неудачном тесте, то мой пользовательский контроллер 404 не вызывается. Я просто получаю простой ответ 404, без пользовательского 404, который упакован со всеми шаблонами моего сайта.

Например:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^testmee\.css$ - [NC,R=410]

Боюсь, я потратил немного вашего времени. Мои извенения. Я никогда не думал, что код Prestashop будет форсировать 404 в зависимости от типа файла, но я не вижу другого объяснения. Я мог бы покопаться в этом и, возможно, найти место в Контроллерах, которое это делает. Должен сделать перерыв, хотя.

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Мне не удалось определить, почему из-за конфигурации сервера или кода сайта директива ответа 410 Gone в htaccess была переопределена ответом 404, поэтому пришлось сделать что-то вроде this , чтобы сообщить googlebot об остановкепоиск CSS / JS-файлов, которые периодически удаляются (и переименовываются при регенерации).

в .htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule v_(.*)_(.*)$ /410response.php [L]

в 410response.php, помещенном в корень:

<?php header($_SERVER['SERVER_PROTOCOL'].' 410 Gone');

ОБНОВЛЕНИЕ I

Ответ 404 при попытке использовать htaccess для директивы 410 был вызван сервером из-за того, что сервер явно имел пользовательский 410документ, который, по-видимому, перенаправлен на 404. Добавление директивы, чтобы предотвратить это, затем разрешило использование htaccess для возврата 410 для совпадений с образцом в RewriteRule.(Я подумал, что вчера уже проверил, будет ли это работать, поскольку @MrWhite в своем ответе выше сказал, что для управления сервером может использоваться пользовательский 410; сегодня при выполнении этой проверки он работал и указал, что сервер 410-toПеренаправление -404 отменяло мою директиву 410.)

ErrorDocument 410 default
RewriteRule test\.txt$ - [NC,R=410]

MrWhite!Я нашел это решение в одном из ваших сообщений на Stack Exchange.

1 голос
/ 31 мая 2019

Это не совсем солидный ответ, это больше, чем попытаться помочь отладить это и разрушить некоторые мифы ...

Я подтвердил, используя phpinfo(), что REQUEST_URIсодержит начальную косую черту

Да, серверная переменная REQUEST_URI Apache действительно содержит начальную косую черту.Он содержит полный URL-путь.

Однако серверная переменная REQUEST_URI Apache не обязательно совпадает с суперглобальным $_SERVER['REQUEST_URI'] PHP - на самом деле, это совсем не одно и то же.Между этими переменными есть некоторые существенные различия (в некоторых случаях, возможно, немного неудачно, что они имеют одно и то же имя).В частности, суперглобальный код PHP содержит начальный URL-адрес из запроса и содержит строку запроса (если есть) и не кодируется в%.Принимая во внимание, что серверная переменная Apache с тем же именем содержит переписанный URL (не обязательно запрашиваемый URL) и не содержит строку запроса и является% -декодированной.

Так вот почему яспрашивал, есть ли у вас другие директивы mod_rewrite.Вы могли бы очень хорошо иметь конфликт.Если другая директива переписывает URL-адрес, то условие никогда не будет соответствовать (несмотря на то, что суперглобальный PHP предлагает это).

Казалось бы, если я поставлю это наверх, флаг Last завершит обработкудля этой поездки верните 410

Эта директива должна обязательно идти вверху файла .htaccess, чтобы избежать перезаписи URL ранее.Флаг L на самом деле является излишним при использовании с R=410 (что-либо кроме 3xx) - в данном случае это подразумевается.

Затем я изменяю результат на «throw»410 "и он выбрасывает 404.

Это, безусловно, может быть вызвано переопределением на стороне сервера.Но вы можете бросить 410 в других ситуациях, так что, похоже, это исключает.Однако вы можете сбросить документ об ошибке в .htaccess, если сомневаетесь (если вы уже не используете пользовательский документ об ошибке):

ErrorDocument 410 default
RewriteCond %{REQUEST_URI} ^/dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ - [R=410,L]

, хотя это не такна самом деле, чтобы изменить поведение правила, вам не нужна первая директива RewriteCond, которая проверяет соответствие REQUEST_URI.Вместо этого вы должны выполнить эту проверку в шаблоне RewriteRule (который будет более эффективным, поскольку он обрабатывается первым).Например:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^dir1/dir2/dir3/v_9991_0726dd5b5e8dd67a214c0c243436d131_all\.css$ - [NC,R=410]

Флаг NC должен быть лишним.

Тем не менее, конфликт с существующими директивами является наиболее вероятной причиной.Удалите все остальные директивы.Вы все еще видите такое же поведение?


Вы можете проверить значение серверной переменной REQUEST_URI.Вы можете либо выполнить перенаправление и передать REQUEST_URI в качестве параметра URL-адреса, либо установить переменные среды (но вам нужно будет следить за REDIRECT_<var> для каждого перезаписи).

Например, вверхувашего .htaccess (или везде, где вы пытаетесь это сделать):

RewriteCond %{QUERY_STRING} ^$
RewriteRule ^ /test.php?var=%{REQUEST_URI} [NE,R,L]

Создан фиктивный файл test.php, чтобы избежать внутреннего подзапроса к документу об ошибке.

...