Urlencoded

О системе

У меня есть 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

Ответ 1

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-адреса.

Ответ 2

Замените% 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

Ответ 3

В Apache, AllowEncodedSlashes On будет препятствовать немедленному отклонению запроса с помощью 404.

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

Ответ 4

$encoded_url = str_replace('%2F', '/', urlencode($url));

Ответ 5

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

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

Я сначала заменю косую черту html, а затем кодирую url.

Ответ 6

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

Ответ 7

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

например. Drupal.org использует% 21 (символ метки excalamation!) Для представления косой черты в параметре 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 и преобразуйте его обратно на сервер косой черты.

Ответ 8

Стандартное решение этой проблемы состоит в том, чтобы разрешить слэши, задав параметр, который может содержать слэш, последний параметр в URL-адресе.

Для URL-кода кода продукта у вас тогда будет...

mysite.com/product/details/PR12345/22

Для поискового запроса у вас будет

http://project/search_exam/0/search_subject/0/keyword/Psychology/Management

(Ключевое слово здесь - Психология/Управление)

Это не очень большая работа для обработки первых "названных" параметров, а затем остальных оставшихся для обозначения кода продукта или ключевого слова.

В некоторых средах этот механизм встроен в свои определения маршрутизации.

Это не применимо к случаю использования, включающему два параметра, которые содержат слэш.

Ответ 9

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

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

после декодирования термина

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

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

Ответ 10

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

Лучший способ, который я нашел, - просто преобразовать параметр в кодировку 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); 

Ответ 11

Я использую функцию javascript encodeURI() для части URL, которая имеет косые черты, которые следует рассматривать как символы вместо http-адреса. Например:

"/api/activites/" + encodeURI("?categorie=assemblage&nom=Manipulation/Finition")

см. http://www.w3schools.com/tags/ref_urlencode.asp

Ответ 12

Я решил это, используя две пользовательские функции:

function slash_replace($query){

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

function slash_unreplace($query){

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

Поэтому для кодирования я мог бы позвонить:

rawurlencode(slash_replace($param))

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

slash_unreplace(rawurldecode($param);

Ура!

Ответ 13

Вы можете использовать %2F, если используете его таким образом:
?param1=value1&param2=value%2Fvalue

но если вы используете /param1=value1/param2=value%2Fvalue, это вызовет ошибку.