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

Apache2: проблемы с сопоставлением акцентированных символов в строке запроса с помощью RewriteCond и RewriteRule

Работа на сайте, где планируется переместить URL-адреса из формата строки запроса в формат на основе чисел. Существует множество URL-адресов, в которых есть неэкранированные акцентированные и похожие символы UTF8. Эта проблема? Кажется, я не могу заставить Apache2 правильно сопоставлять символы с диакритическими знаками и выполнять перезапись. Все это я делаю в конфиге Apache2.

Например, этот URL:

http://great.website.example.com/?place=cafe

Будет работать, как ожидалось, с этим параметром Apache2 RewriteRule:

  RewriteCond %{QUERY_STRING} ^(place|location)=cafe
  RewriteRule ^/find/$ /find/1234? [L,R=301]

Теперь посмотрите на этот URL. Обратите внимание на акцентированный é:

http://great.website.example.com/?place=café

Почему этот URL не работает со следующей настройкой Apache2 RewriteRule:

  RewriteCond %{QUERY_STRING} ^(place|location)=café
  RewriteRule ^/find/$ /find/1234? [L,R=301]

Оба эти правила должны переписать URL-адрес следующим образом:

http://great.website.example.com/find/1234

Но пример с ударением é просто не работает. Может быть, подстановочный знак подойдет, но я тоже не могу заставить его работать.

Ваш /?place=café будет закодированный по URL браузером, чтобы /?place=caf%C3%A9 и это то, что вы должны сопоставить.

Вы можете использовать RewriteMap для отмены экранирования за вас. как это:

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

Во второй строке RewriteCond я использую% 2, поскольку% 1 будет содержать либо «местоположение», либо «место».

Однако добавление большого количества RewriteRules в вашу конфигурацию для сопоставления слов с числами будет большим ударом по производительности на вашем сервере, и его будет сложно поддерживать. Лучшее решение - использовать и для этого RewriteMap.

Например, предположим, что /etc/apache2/places.txt содержит:

café    1234
shop   1235
...

Тогда это сработает для вас:

RewriteMap unescape int:unescape
RewriteMap places   txt:/etc/apache2/places.txt

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   (.*)
RewriteRule ^/find/$         /find/${places:%1}? [L,R]

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

Более подробную информацию вы можете найти в документации: http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

В связанный вопрос, кто-то предложил использовать RewriteMap для вызова внешней программы для перезаписи URL.

Также: Возможно, запрос на самом деле совсем другой? Браузер мог внутренне преобразовать акцентированные символы в кодировку ASCII в URL-адресе? Например. '%20' скорее, чем ' '.