прямая косая черта urlencoded ломает URL - PullRequest
70 голосов
/ 13 июля 2010

О системе

У меня есть URL-адреса этого формата в моем проекте: -

http://project_name/browse_by_exam/type/tutor_search/keyword/class/new_search/1/search_exam/0/search_subject/0

Где пара ключевое слово / класс означает поиск по ключевому слову "class".

У меня есть общий файл 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

Ответы [ 13 ]

141 голосов
/ 13 июля 2010

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.

8 голосов
/ 26 февраля 2015

Заменить% 2F на% 252F после кодирования URL

PHP

function custom_http_build_query($query=array()){

    return str_replace('%2F','%252F', http_build_query($query));
}

Обработка запроса через htaccess

.htaccess

RewriteCond %{REQUEST_URI} ^(.*?)(%252F)(.*?)$ [NC]
RewriteRule . %1/%3 [R=301,L,NE]

Ресурсы

http://www.leakon.com/archives/865

4 голосов
/ 28 апреля 2011

В Apache AllowEncodedSlashes On предотвратит немедленный отклонение запроса с 404.

Еще одна идея, как это исправить.

3 голосов
/ 03 декабря 2015

У меня была та же проблема с косой чертой в url get param, в моем случае работает следующий php-код:

$value = "hello/world"
$value = str_replace('/', '/', $value;?>
$value = urlencode($value);?>
# $value is now hello%26%2347%3Bworld

Сначала я заменяю косую черту на html-сущность, а затем делаю кодировку url.

3 голосов
/ 12 марта 2014
$encoded_url = str_replace('%2F', '/', urlencode($url));
2 голосов
/ 17 мая 2011

В моей учетной записи хостинга эта проблема была вызвана правилом ModSecurity, которое было установлено для всех учетных записей автоматически. Когда я сообщил об этой проблеме, их администратор быстро удалил это правило для моей учетной записи.

1 голос
/ 02 сентября 2015

Используйте другой символ и замените косую черту на стороне сервера

Например, Drupal.org использует% 21 (символ восклицательного знака!) Для представления косой черты в параметре URL.

Обассылки ниже работают:

https://api.drupal.org/api/drupal/includes%21common.inc/7

https://api.drupal.org/api/drupal/includes!common.inc/7

Если вы беспокоитесь, что персонаж может конфликтовать с символом в параметре, используйте комбинациюсимволов.

Таким образом, ваш URL будет http://project_name/browse_by_exam/type/tutor_search/keyword/one_-!two/new_search/1/search_exam/0/search_subject/0

изменить его с помощью js и преобразовать его обратно в слэш-сервер.

0 голосов
/ 27 апреля 2019

Вот мое скромное мнение.!!!!Не !!!!измените настройки на сервере, чтобы ваши параметры работали правильно.Это бомба замедленного действия, ожидающая когда-нибудь, когда вы меняете серверы.

Лучший способ, который я нашел, - просто преобразовать параметр в кодировку base 64.Поэтому в моем случае я вызываю php-сервис из Angular и передаю параметр, который может содержать любое значение.

Поэтому мой машинописный код в клиенте выглядит следующим образом:

    private encodeParameter(parm:string){
    if (!parm){
        return null;
    }
    return btoa(parm);
}

И получить параметр в php:

    $item_name = $request->getAttribute('item_name');
    $item_name = base64_decode($item_name); 
0 голосов
/ 13 июня 2017

просто для меня использовать base64_encode

$term = base64_encode($term) 
$url = $youurl.'?term='.$term

после того, как вы расшифруете термин

$term = base64_decode($['GET']['term'])

таким образом закодируйте "/" и "\"

0 голосов
/ 03 октября 2016

Я решил это с помощью 2 пользовательских функций, например:

function slash_replace($query){

    return str_replace('/','_', $query);
}

function slash_unreplace($query){

    return str_replace('_','/', $query);
}

Так что для кодирования я мог бы позвонить:

rawurlencode(slash_replace($param))

и для декодирования я мог бы позвонить

slash_unreplace(rawurldecode($param);

Ура!

...