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

как переписать "% 25" в URL

Программное обеспечение моего веб-сайта заменяет пробелы в URL-адресе символами '+'. Правильная ссылка будет выглядеть так: 'http://www.schirmacher.de/display/INFO/How+to+reattach+a+disk+to+XenServer' например.

Некоторые веб-сайты ссылаются на эту статью, но каким-то образом их встроенный редактор не может обрабатывать кодировку, поэтому то, что я вижу в файлах журнала httpd, на самом деле

GET /display/INFO/How%2525252bto%2525252breattach%2525252ba%2525252bdisk%2525252bto%2525252bXenServer

что, конечно же, приводит к ошибке 404. Кажется, что символ «+» кодируется как «% 2b», а затем символ «%» кодируется как «% 25» - несколько раз.

Поскольку существует много таких ссылок на разные страницы с разных веб-сайтов, я хотел бы переписать URL-адрес, чтобы посетители получали правильную страницу.

Вот моя попытка, которая не работает:

RewriteRule ^(.*)%25(.*)$ $1%$2 [R=301]

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

В примере входного URL-адреса правило следует переписать на

/display/INFO/How%25252bto%2525252breattach%2525252ba%2525252bdisk%2525252bto%2525252bXenServer

с последующим перенаправлением, затем его следует переписать на

/display/INFO/How%252bto%2525252breattach%2525252ba%2525252bdisk%2525252bto%2525252bXenServer

и снова к

/display/INFO/How%2bto%2525252breattach%2525252ba%2525252bdisk%2525252bto%2525252bXenServer

и так далее. Наконец, после множества перенаправлений я должен был уйти

/display/INFO/How%2bto%2breattach%2ba%2bdisk%2bto%2bXenServer

который является действительным URL-адресом, эквивалентным / display / INFO / How + to + reattach + a + disk + to + XenServer.

Моя проблема в том, что выражение вообще не соответствует, поэтому оно даже не заменяет ни единого вхождения% 25.

Я понимаю, что существует ограничение на количество перенаправлений, и мне действительно следует использовать флаг [N], однако я даже не могу правильно сделать первый шаг.


@ Бен Ли: спасибо за подробный ответ. Я потратил несколько часов на эту проблему. Вот что я выяснил:

  1. Любая строка «% 25» в URL-адресе преобразуется в «%» до того, как mod_rewrite ее увидит. Итак, RewriteRule ^ (.)% 25 (.) $ не соответствует "% 25" в URL-адресе, фактически соответствует "% 2525".

  2. Наличие обратной косой черты не имеет значения. Похоже, что знак «%» в моем случае не интерпретируется как обратная ссылка, возможно потому, что раньше не было инструкции RewriteCond. Но, наверное, лучше использовать, на всякий случай.

  3. Строка с [L, R = 301] неверна. Он будет пытаться перенаправить для каждого совпадения% 2b, но есть предел разрешенных перенаправлений, и он не удастся, если их будет больше.

Вот строки mod_rewrite, которые я использую:

RewriteRule ^(.*)\%25(.*\%25.*)$ $1%$2 [N]
RewriteRule ^(.*)\%25(.*)$ $1%$2 [R=301,L]

RewriteRule ^(.*)\%2b(.*\%2b.*)$ $1+$2 [N]
RewriteRule ^(.*)\%2b(.*)$ $1+$2 [R=301,L]

Третья строка заменит все последовательности% 2b, кроме одной, на символ "+". Когда осталась только одна последовательность% 2b, четвертая строка будет соответствовать, вызывая перенаправление.

Первая и вторая строки в основном одинаковы, но с последовательностью% 25. Необходимо иметь правило с флагом [R] для каждой возможной последовательности символов, потому что я также использую mod_proxy / mod_jk, и перенаправление будет гарантировать, что результирующий URL-адрес снова будет передан каждому модулю. В противном случае httpd попытается получить URL-адрес с диска, что в моем случае не удастся.

Вот ваше первоначальное правило с [L] добавлено для обозначения «последнего»:

RewriteRule ^(.*)%25(.*)$ $1%$2 [L,R=301]

После этого здесь возникает несколько проблем. Во-первых, знаки процента RewriteRule узоры имеют особое значение; они обозначают начало обратной ссылки на RewriteCond. Вы можете обойти это, экранируя их (используя обратную косую черту):

RewriteRule ^(.*)\%25(.*)$ $1%$2 [L,R=301]

Во-вторых, когда вы вставляете % в замене, он не будет рассматривать это как часть части, закодированной в uri. Это переводится как буквальный знак процента. В исходном URL-адресе, который вы получаете, первый %25"также преобразуется в буквальный знак процента. Таким образом, приведенное выше правило приведет к буквальному %25s или буквальный %2b в URL-адресе вместо разрешения % или +. Поэтому вам нужно вручную решить их самостоятельно.

RewriteRule ^(.*)\%25(.*)$ $1%$2
RewriteRule ^(.*)\%2b(.*)$ $1+$2 [L,R=301]

Наконец, поскольку у вас нет ни одного 25 после начального %, но потенциально многие используют [N] для обозначения «следующий». Это в основном означает «начать процесс с самого начала, но использовать мой новый URL в качестве ввода». Так что это будет иметь дело с любым количеством 25s после процента:

RewriteRule ^(.*)\%25(.*)$ $1%$2 [N]
RewriteRule ^(.*)\%2b(.*)$ $1+$2 [L,R=301]

Примечание. Это должно работать, если вы настраиваете свое правило в обычных конфигурациях apache. Если вы настраиваете его как .htaccess, ведущие косые черты исключаются из строки, проверяемой регулярным выражением, и в этом случае вам придется добавить их обратно в себя:

RewriteRule ^(.*)\%25(.*)$ /$1%$2 [N]
RewriteRule ^(.*)\%2b(.*)$ /$1+$2 [L,R=301]

ОБНОВИТЬ: Сейчас у меня нет возможности протестировать, но, просмотрев документацию, я увидел вариант NE для "выхода без выхода", заставляющего проц в результате работать как обычные маркеры кодирования. Если я правильно понял, это означает, что правило можно упростить до следующего:

RewriteRule ^(.*)\%25(.*)$ $1%$2 [NE,N,L,R=301]

Но опять же, это не проверено, и я никогда не использовал NE flag, поэтому я могу неправильно это понять. Если вы протестируете это и обнаружите, что он работает, дайте мне знать, и я удалю это ОБНОВЛЕНИЕ и просто исправлю приведенный выше ответ, чтобы включить эту более простую версию.