htaccess RewriteRule с буквальными вопросительными знаками (не строка запроса) - PullRequest
0 голосов
/ 05 сентября 2018

Мне нужно иметь возможность сопоставлять вопросительные знаки, потому что произошла ошибка в кодировке переведенного текста, и часть URL была жестко запрограммирована с вопросительными знаками в них. Вот пример URL, который мне нужно переписать:

https://example.com/Documentation/Product????/index.html

Вот мое текущее правило переписывания. Это работает, когда символы, следующие за «Продуктом», не являются вопросительными знаками, но когда они есть, правило не применяется.

RewriteRule "^Documentation/Product[^/]+/(.*)$" "https://s3.amazonaws.com/company-documentation/Help/Product/$1" [L,NC]

Как сделать так, чтобы в этом правиле знаки вопроса тоже считались символами? Я не могу ожидать, что в URL будут только вопросительные знаки, а не исходные неанглийские символы, поэтому я хочу, чтобы приведенное выше правило совпадало как с вопросительными знаками, так и с любым другим символом.

Я нашел эту тему, которая кажется актуальной, но флаги не помогают, и в ответе не объясняется, как преодолеть проблему, упомянутую в «В стороне». https://webmasters.stackexchange.com/questions/107259/url-path-with-encoded-question-mark-results-in-incorrect-redirect-when-copied-to

1 Ответ

0 голосов
/ 05 сентября 2018
https://example.com/Documentation/Product????/index.html

Вы говорите, что это "не строка запроса", но на самом деле это именно то, что есть. И именно поэтому вы не можете сопоставить его с шаблоном RewriteRule . Приведенный выше URL разделен следующим образом:

  • URL-путь: /Documentation/Product (соответствует шаблону RewriteRule )
  • Строка запроса: ???/index.html (примечание 3 ? - первая строка запроса начинает)

Чтобы соответствовать строке запроса, вам понадобится дополнительная директива RewriteCond, которая проверяет серверную переменную QUERY_STRING.

Например, чтобы соответствовать вышеуказанному URL, вам нужно сделать что-то вроде:

RewriteCond %{QUERY_STRING} ^\?*/index\.html
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/index.html [NC,R,L]

Это соответствует любому числу ошибочных ? в начале строки запроса.

Я добавил флаг R (redirect). Ваша директива (без флага R) в любом случае вызовет внешнее перенаправление (поскольку вы указываете абсолютный URL-адрес в подстановке ), но здесь гораздо лучше быть явным. Это также временное (302) перенаправление. Если это значение должно быть постоянным (301), измените его на R=301, но только после того, как вы подтвердите, что оно работает нормально (301s кэшируется браузером, поэтому тестирование может быть проблематичным).


UPDATE:

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

Только если в URL-адресе есть вопросительные знаки, будет строка запроса, поэтому я думаю, что желательно разделить эти два правила.

Если в начале строки запроса могут быть какие-либо ошибочные символы и если вы хотите захватить конечную часть URL (как вы делаете в своей исходной директиве, например, index.html), то вы можете изменить выше читать:

RewriteCond %{QUERY_STRING} /(.*)$
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/%1 [NC,R,L]

Обратите внимание на обратную ссылку %1 (в отличие от $1) в строке substitution . Это обратная ссылка на захваченную группу в последнем сопоставленном CondPattern (т. Е. /(.*)$).

Вы можете следовать этому с помощью существующей директивы (но не забудьте включить флаг R) для более «обычных» URL, которые не содержат ? (т. Е. Строку запроса).

Примечание: окружение аргументов в двойных кавычках совершенно необязательно в этом примере. Они обязательны , если у вас есть неэкранированные пробелы в шаблоне или подстановка аргументы.

В итоге

# Redirect URLs of the form:
# "/Documentation/Product?<anything#1>/<anything#2>"
RewriteCond %{QUERY_STRING} /(.*)$
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/%1 [NC,R,L]

# Redirect URL-paths of the form (no query string):
# "/Documentation/Product<something>/<anything>"
RewriteRule ^Documentation/Product[^/]+/(.*) https://s3.amazonaws.com/company-documentation/Help/Product/$1 [NC,R,L]
...