Решение на самом деле может быть довольно простым, хотя оно будет работать только в Apache 2.2 и более поздних версиях из-за использования флага B
.Я не уверен, правильно ли он заботится о каждом случае (по общему признанию, я немного скептически отношусь к тому, что это не требует больше работы, чем эта), но я уверен, что это следует из исходного кода.
Имейте в виду, что значение REQUEST_URI
не обновляется преобразованиями mod_rewrite, поэтому, если ваше приложение использует это значение для определения запрошенного URL-адреса, сделанные вами изменения в любом случае не будут видны.
Хорошая новость заключается в том, что это можно сделать в .htaccess, поэтому у вас есть возможность оставить основную конфигурацию без изменений, если она работает лучше для вас.
RewriteEngine On
# Make sure this is only done once to avoid escaping the escapes...
RewriteCond %{ENV:REDIRECT_STATUS} ^$
# Check if we have anything to bother escaping (likely unnecessary...)
RewriteCond $0 [^\w]+
# Rewrite the entire URL by escaping the backreference
RewriteRule ^.*$ $0 [B]
Итак, почему есть необходимость?использовать флаг B
вместо того, чтобы позволить mod_rewrite экранировать переписанный URL автоматически?Когда mod_rewrite автоматически экранирует URL-адрес, он использует ap_escape_uri
(который по некоторым причинам был превращен в макрос для ap_os_escape_path
), функцию, которая экранирует ограниченное подмножество символов.Однако флаг B
использует внутреннюю функцию модуля под названием escape_uri
, которая смоделирована на PHP urlencode
функция.
Реализация escape_uri
в модуле предполагаетчто буквенно-цифровые символы и символы подчеркивания остаются как есть, пробелы преобразуются в +, а все остальное преобразуется в его экранированный эквивалент.Похоже, это поведение, которое вам нужно, поэтому, вероятно, оно должно работать.
Если нет, у вас есть возможность настроить внешнюю программу RewriteMap
, которая может манипулировать вашим входящимURL-адреса в правильном формате.Однако это требует манипулирования конфигурацией Apache, а скрипт-отступник может вызвать проблемы для сервера в целом, поэтому я не считаю его идеальным решением, если его можно избежать.