Работа на сайте, где планируется переместить 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
' скорее, чем ' '.