О системе
У меня есть URL этого формата в моем проекте:-
http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0
Где пара ключевого слова/класса означает поиск с ключевым словом "класса".
У меня есть общий index.php файл, который выполняется для каждого модуля в проекте. Существует только переписать правило удалить index.php из URL:-
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L,QSA]
Я использую urlencode () при подготовке поискового URL и urldecode () при чтении поискового URL.
Проблема
Только символ наклонной черты вправо повреждает URL, вызывающие 404 ошибки "Страница не найдена". Например, если я ищу one/two
URL
http://project_name/browse_by_exam/type/tutor_search/keyword/one%2Ftwo/new_search/1/search_exam/0/search_subject/0/page_sort/
Как я фиксирую это? Я должен сохранить index.php скрытым в URL. Иначе, если бы это было не нужно, не было бы никакой проблемы с наклонной чертой вправо, и я, возможно, использовал этот URL:-
http://project_name/index.php?browse_by_exam/type/tutor_search/keyword/one
%2Ftwo/new_search/1/search_exam/0/search_subject/0
Apache запрещает все URL с %2F
в части пути, по причинам безопасности: скрипты не могут нормально (т.е. без переписывания) отличить %2F
от /
из-за того, что переменная окружения PATH_INFO
автоматически декодирует URL (это глупо, но это давняя часть спецификации CGI, поэтому с этим ничего нельзя поделать).
Вы можете отключить эту функцию с помощью директивы AllowEncodedSlashes
но учтите, что другие веб-серверы все равно запретят ее (без возможности отключения), и что другие символы также могут быть запрещены (например, %5C
), и что %00
, в частности, всегда будет блокироваться как Apache, так и IIS. Так что если ваше приложение зависит от возможности иметь %2F
или другие символы в части пути, вы ограничиваете свои возможности совместимости/развертывания.
Я использую urlencode() при подготовке поискового URL
Для экранирования частей пути следует использовать rawurlencode()
, а не urlencode()
. urlencode()
неправильно назван, на самом деле он предназначен для application/x-www-form-urlencoded
данных, таких как в строке запроса или теле POST-запроса, а не для других частей URL.
Разница в том, что +
не означает пробел в частях пути. rawurlencode()
вместо этого правильно выдаст %20
, который будет работать как в кодированных данных, так и в других частях URL.