urlencode против rawurlencode?


380

Если я хочу создать URL с использованием переменной, у меня есть два варианта кодирования строки. urlencode()и rawurlencode().

Каковы именно различия и что является предпочтительным?


1
Мне бы очень хотелось увидеть некоторые причины для выбора одного над другим (например, проблемы, которые могут возникнуть с одним или другим), я (и я ожидаю, что другие) хочу иметь возможность просто выбрать один и использовать его навсегда с меньше всего суеты, поэтому я начал щедрость по этому вопросу.
Kzqai

29
@ Чальвак: Если вы хотите выбрать только один, выберите rawurlencode. Вы редко столкнетесь с системой, которая задыхается, когда заданы пробелы, закодированные как %20, в то время как системы, которые подавляются пробелами, закодированными как, +являются более распространенными.
Аномия

Ответы:


326

Это будет зависеть от вашей цели. Если важна совместимость с другими системами, тогда кажется, что стоит использовать rawurlencode. Единственное исключение - устаревшие системы, которые ожидают, что строка запроса будет следовать стилю кодирования формы пробелов, закодированных как + вместо% 20 (в этом случае вам нужен urlencode).

rawurlencode следует RFC 1738 до PHP 5.3.0 и RFC 3986 впоследствии (см. http://us2.php.net/manual/en/function.rawurlencode.php )

Возвращает строку, в которой все не алфавитно-цифровые символы, кроме -_. ~, Были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры. Эта кодировка описана в »RFC 3986 для защиты буквенных символов от интерпретации в качестве специальных разделителей URL-адресов и для защиты URL-адресов от искажения средствами передачи с преобразованиями символов (например, в некоторых системах электронной почты).

Примечание к RFC 3986 против 1738. rawurlencode до php 5.3 кодировал символ тильды ( ~) в соответствии с RFC 1738. Однако, начиная с PHP 5.3, rawurlencode следует RFC 3986, который не требует кодирования символов тильды.

urlencode кодирует пробелы как знаки плюс (а не как %20в rawurlencode) (см. http://us2.php.net/manual/en/function.urlencode.php )

Возвращает строку, в которой все не алфавитно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры и пробелы, закодированные как знаки плюс (+). Он кодируется так же, как кодируются опубликованные данные из WWW-формы, так же, как в типе носителя application / x-www-form-urlencoded. Это отличается от кодировки »RFC 3986 (см. Rawurlencode ()) тем, что по историческим причинам пробелы кодируются как знаки плюс (+).

Это соответствует определению для application / x-www-form-urlencoded в RFC 1866 .

Дополнительное чтение:

Вы также можете посмотреть обсуждение по адресу http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode .

Также стоит посмотреть RFC 2396 . RFC 2396 определяет допустимый синтаксис URI. Основная часть, которая нас интересует, - из 3.4 Query Component:

В компоненте запроса символы зарезервированы.";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"

Как вы можете видеть, +это зарезервированный символ в строке запроса и, следовательно, должен быть закодирован в соответствии с RFC 3986 (как в rawurlencode).


27
Так что же предпочтительнее?
Гэри Уиллоуби

79
rawurlencode. идти со стандартом в этом случае. urlencode хранится только для устаревшего использования
Джонатан Фингланд

2
Большое спасибо, вот что я подумал, я просто хотел получить второе мнение, прежде чем начать обновлять много кода.
Гари Уиллоуби

3
Я думаю, что это rawurlencode, который кодирует не пробелы как знаки плюс, а как% 20s
BigName 20.10.10

2
@Pindatjuh: Часть, которую вы процитировали Единственное исключение - это устаревшие системы, которые ожидают, что строка запроса будет следовать стилю кодирования формы пробелов, кодированных как + вместо% 20 (в этом случае вам нужен urlencode), что означает, что rawurlencode подходит для большинства ситуаций. некоторые системы ожидают, что пробелы будут закодированы как + (знак плюс). Для таких систем лучше использовать urlencode.
Джонатан Фингланд

213

Доказательство есть в исходном коде PHP.

Я проведу вас через быстрый процесс того, как найти подобные вещи самостоятельно в будущем в любое время. Потерпите меня, будет много исходного кода на C, который вы можете просмотреть (я объясняю это). Если вы хотите освежить в памяти C, то хорошее место для начала - наша SO wiki .

Загрузите исходный код (или воспользуйтесь http://lxr.php.net/, чтобы просмотреть его в Интернете), grep для всех файлов имени функции, вы найдете что-то вроде этого:

PHP 5.3.6 (последняя на момент написания статьи) описывает две функции в своем родном коде C в файле url.c .

RawUrlEncode ()

PHP_FUNCTION(rawurlencode)
{
    char *in_str, *out_str;
    int in_str_len, out_str_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
                              &in_str_len) == FAILURE) {
        return;
    }

    out_str = php_raw_url_encode(in_str, in_str_len, &out_str_len);
    RETURN_STRINGL(out_str, out_str_len, 0);
}

UrlEncode ()

PHP_FUNCTION(urlencode)
{
    char *in_str, *out_str;
    int in_str_len, out_str_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
                              &in_str_len) == FAILURE) {
        return;
    }

    out_str = php_url_encode(in_str, in_str_len, &out_str_len);
    RETURN_STRINGL(out_str, out_str_len, 0);
}

Хорошо, так что здесь отличается?

По сути, они оба вызывают две разные внутренние функции: php_raw_url_encode и php_url_encode

Так что иди ищи эти функции!

Давайте посмотрим на php_raw_url_encode

PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
{
    register int x, y;
    unsigned char *str;

    str = (unsigned char *) safe_emalloc(3, len, 1);
    for (x = 0, y = 0; len--; x++, y++) {
        str[y] = (unsigned char) s[x];
#ifndef CHARSET_EBCDIC
        if ((str[y] < '0' && str[y] != '-' && str[y] != '.') ||
            (str[y] < 'A' && str[y] > '9') ||
            (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
            (str[y] > 'z' && str[y] != '~')) {
            str[y++] = '%';
            str[y++] = hexchars[(unsigned char) s[x] >> 4];
            str[y] = hexchars[(unsigned char) s[x] & 15];
#else /*CHARSET_EBCDIC*/
        if (!isalnum(str[y]) && strchr("_-.~", str[y]) != NULL) {
            str[y++] = '%';
            str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4];
            str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 15];
#endif /*CHARSET_EBCDIC*/
        }
    }
    str[y] = '\0';
    if (new_length) {
        *new_length = y;
    }
    return ((char *) str);
}

И, конечно же, php_url_encode:

PHPAPI char *php_url_encode(char const *s, int len, int *new_length)
{
    register unsigned char c;
    unsigned char *to, *start;
    unsigned char const *from, *end;

    from = (unsigned char *)s;
    end = (unsigned char *)s + len;
    start = to = (unsigned char *) safe_emalloc(3, len, 1);

    while (from < end) {
        c = *from++;

        if (c == ' ') {
            *to++ = '+';
#ifndef CHARSET_EBCDIC
        } else if ((c < '0' && c != '-' && c != '.') ||
                   (c < 'A' && c > '9') ||
                   (c > 'Z' && c < 'a' && c != '_') ||
                   (c > 'z')) {
            to[0] = '%';
            to[1] = hexchars[c >> 4];
            to[2] = hexchars[c & 15];
            to += 3;
#else /*CHARSET_EBCDIC*/
        } else if (!isalnum(c) && strchr("_-.", c) == NULL) {
            /* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
            to[0] = '%';
            to[1] = hexchars[os_toascii[c] >> 4];
            to[2] = hexchars[os_toascii[c] & 15];
            to += 3;
#endif /*CHARSET_EBCDIC*/
        } else {
            *to++ = c;
        }
    }
    *to = 0;
    if (new_length) {
        *new_length = to - start;
    }
    return (char *) start;
}

Прежде чем я двинусь вперёд, EBCDIC - это другой набор символов , похожий на ASCII, но полный конкурент. PHP пытается справиться с обоими. Но в основном это означает, что байт EBCDIC 0x4c байт не Lв ASCII, это на самом деле <. Я уверен, что вы видите здесь путаницу.

Обе эти функции управляют EBCDIC, если веб-сервер определил его.

Кроме того, они оба используют hexcharsпоиск по типу символов (думаю, тип строки) , чтобы получить некоторые значения, массив описывается так:

/* rfc1738:

   ...The characters ";",
   "/", "?", ":", "@", "=" and "&" are the characters which may be
   reserved for special meaning within a scheme...

   ...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
   reserved characters used for their reserved purposes may be used
   unencoded within a URL...

   For added safety, we only leave -_. unencoded.
 */

static unsigned char hexchars[] = "0123456789ABCDEF";

Кроме того, функции действительно разные, и я собираюсь объяснить их в ASCII и EBCDIC.

Отличия в ASCII:

UrlEncode:

  • Вычисляет начальную / конечную длину входной строки, выделяет память
  • Прогулки по циклу while с шагом до конца строки
  • Хватает настоящего персонажа
  • Если символ равен ASCII Char 0x20 (т. Е. «Пробел»), добавьте +знак в выходную строку.
  • Если это не пробел, и это также не алфавитно-цифровая ( isalnum(c)), а также не и _, -или .символ, то мы выводим %знак в позицию массива 0, чтобы массив выглядел в hexcharsмассив для поиска в os_toasciiмассиве ( массив из Apache, который переводит символ в шестнадцатеричный код) для ключа c(текущий символ), затем мы побитно сдвигаемся вправо на 4, присваиваем это значение символу 1, а позиции 2 мы присваиваем тот же поиск, за исключением того, что преформуем логическое и посмотреть, если значение равно 15 (0xF), и вернуть 1 в этом случае или 0 в противном случае. В конце концов, вы получите что-то закодированное.
  • Если в конце концов это не пробел, это буквенно-цифровой или один из _-.символов, он выводит именно то, что есть.

RAWURLENCODE:

  • Выделяет память для строки
  • Итерации по нему на основе длины, предоставленной в вызове функции (не рассчитывается в функции, как с URLENCODE).

Примечание: многие программисты, вероятно, никогда не видели итерацию цикла for таким образом, это несколько хакерское и не стандартное соглашение, используемое с большинством циклов for, обратите внимание, оно присваивает xи yпроверяет выход при lenдостижении 0, а также увеличивает xи y. Я знаю, это не то, что вы ожидаете, но это правильный код.

  • Назначает текущий символ соответствующей позиции символа в str.
  • Он проверяет, является ли текущий символ буквенно-цифровым или одним из _-.символов, и если это не так, мы делаем почти то же самое назначение, что и с URLENCODE, где он преобразует поиск, однако мы увеличиваем его по-разному, используя y++вместо to[1]этого, потому что Струны строятся по-разному, но в конце концов достигают одной и той же цели.
  • Когда цикл завершен и длина прошла, он фактически завершает строку, назначая \0байт.
  • Возвращает закодированную строку.

Отличия:

  • UrlEncode проверяет пространство, назначает знак +, RawURLEncode - нет.
  • UrlEncode не назначает \0байт строке, как это делает RawUrlEncode (это может быть спорным вопросом)
  • Они повторяются по-разному, можно быть склонным к переполнению искаженными строками, я просто предлагаю это, и я фактически не исследовал.

Они в основном повторяются по-разному, один присваивает знак + в случае ASCII 20.

Отличия в EBCDIC:

UrlEncode:

  • Те же настройки итерации, что и в ASCII
  • Все еще переводим символ "пробел" в знак + . Примечание - я думаю, что это нужно скомпилировать в EBCDIC, или вы получите ошибку? Может кто-нибудь отредактировать и подтвердить это?
  • Он проверяет, является ли текущий символ ранее символом 0, за исключением того, что он является .или -, или ИЛИ меньше, Aно больше, чем символ 9, ИЛИ больше Zи меньше, aно не a _. ИЛИ больше, чем z(да, EBCDIC вроде бы запутался в работе). Если он совпадает с любым из них, выполните поиск, аналогичный найденному в версии ASCII (он просто не требует поиска в os_toascii).

RAWURLENCODE:

  • Те же настройки итерации, что и в ASCII
  • Такая же проверка, как описано в EBCDIC-версии URL Encode, за исключением того, что если он больше z, он исключает ~из URL-кодирования.
  • То же назначение, что и в ASCII RawUrlEncode
  • Все еще добавляя \0байт к строке перед возвратом.

Grand Summary

  • Оба используют одну и ту же таблицу поиска hexchars
  • URIEncode не завершает строку с \ 0, raw делает.
  • Если вы работаете в EBCDIC, я бы предложил использовать RawUrlEncode, так как он управляет тем ~, чего не делает UrlEncode ( это сообщенная проблема ). Стоит отметить, что ASCII и EBCDIC 0x20 являются пробелами.
  • Они повторяются по-разному, кто-то может быть быстрее, кто-то может быть подвержен эксплойтам на основе памяти или строк.
  • URIEncode делает пробел в +, RawUrlEncode делает пробел %20через поиск в массиве.

Отказ от ответственности: я не прикасался к C в течение многих лет, и я не смотрел на EBCDIC действительно очень долгое время. Если я где-то ошибаюсь, дайте мне знать.

Предлагаемые реализации

Исходя из всего этого, rawurlencode - это то, что нужно делать большую часть времени. Как вы видите в ответе Джонатана Фингланда, придерживайтесь его в большинстве случаев. Он имеет дело с современной схемой для компонентов URI, где, как urlencode делает вещи по-старому, где + означает «пробел».

Если вы пытаетесь конвертировать между старым форматом и новыми форматами, убедитесь, что ваш код не искажается и что-то, что является символом +, превращается в пробел путем случайного двойного кодирования или аналогичных сценариев "упс" пространство / 20% / + проблема.

Если вы работаете на более старой системе с более старым программным обеспечением, которое не предпочитает новый формат, придерживайтесь urlencode, однако, я считаю, что% 20 на самом деле будет обратно совместим, как в старом стандартном% 20 работало, просто не было предпочтительным. Дайте ему шанс, если вы готовы играть, дайте нам знать, как это сработало для вас.

По сути, вы должны придерживаться raw, если ваша система EBCDIC действительно не ненавидит вас. Большинство программистов никогда не столкнутся с EBCDIC ни в одной из систем, созданных после 2000 года, может быть, даже 1990 года (это, на мой взгляд, все еще актуально).


Мне никогда не приходилось беспокоиться о двойном кодировании, ведь я должен знать, что я кодировал, так как я думаю, что я делаю кодирование. Поскольку я декодирую все, что получаю, в режиме совместимости, который знает, как обрабатывать + для пространства, я также никогда не сталкивался с проблемами, о которых вы пытаетесь предупредить здесь. Я могу понять, глядя на источник, если мы не знаем, что что-то делает, но что именно мы узнали здесь, чего мы не знали уже из простого выполнения обеих функций. Я знаю, что я предвзят, но не могу не думать, что это зашло слишком далеко. Слава на усилие, хотя! =)
ник-

2
+1, для этой части: «Я верю, что% 20 будет на самом деле обратно совместимым, так как по старому стандарту% 20 работал, просто не был предпочтительным»
Gras Double

3
Хороший ответ, но, может быть, немного излишним?
Риного

38
echo rawurlencode('http://www.google.com/index.html?id=asd asd');

доходность

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd%20asd

пока

echo urlencode('http://www.google.com/index.html?id=asd asd');

доходность

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd+asd

Разница в том, что asd%20asdпротивasd+asd

urlencode отличается от RFC 1738 кодированием пробелов, а +не%20


28

Одна практическая причина выбрать один из других, если вы собираетесь использовать результат в другой среде, например, JavaScript.

В PHP urlencode('test 1')возвращается, 'test+1'а rawurlencode('test 1')возвращается'test%201' как результат.

Но если вам нужно «декодировать» это в JavaScript с помощью функции decodeURI (), тогда decodeURI("test+1")вы получите "test+1"время, decodeURI("test%201")которое даст вам "test 1"результат.

Другими словами, пробел (""), закодированный urlencode в plus ("+") в PHP, не будет должным образом декодирован decodeURI. в JavaScript.

В таких случаях следует использовать PHP-функцию rawurlencode .


6
Это, безусловно, лучший ответ, который я видел. Это предложение для использования на примере из реального мира. Кроме того, это сжато.
Dotancohen

Это хороший пример, хотя я предпочитаю json_encodeи JSON.parseдля этого.
Фабрисио Мате

21

Я считаю, что пробелы должны быть закодированы как:

  • %20 при использовании внутри компонента пути URL
  • +при использовании внутри компонента строки запроса URL или данных формы (см. 17.13.4 Типы содержимого формы )

В следующем примере показано правильное использование rawurlencodeи urlencode:

echo "http://example.com"
    . "/category/" . rawurlencode("latest songs")
    . "/search?q=" . urlencode("lady gaga");

Вывод:

http://example.com/category/latest%20songs/search?q=lady+gaga

Что произойдет, если вы закодируете компоненты пути и строки запроса наоборот? Для следующего примера:

http://example.com/category/latest+songs/search?q=lady%20gaga
  • Веб-сервер будет искать каталог latest+songs вместоlatest songs
  • Параметр строки запроса qбудет содержатьlady gaga

2
«Параметр строки запроса qбудет содержать lady gaga» Что еще он будет содержать в противном случае? qКажется, что параметр запроса имеет одно и то же значение, передаваемое $_GETмассиву, независимо от использования rawurlencodeили urlencodeв PHP 5.2+. Тем не менее, urlencodeкодирует в application/x-www-form-urlencodedформате, который по умолчанию для запросов GET, поэтому я иду с вашим подходом. +1
Фабрицио Мате

2
Я хотел уточнить, что оба +и %20декодируются как пространство при использовании в строках запроса.
Салман А

5

Разница заключается в возвращаемых значениях, то есть:

urlencode () :

Возвращает строку, в которой все не алфавитно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры и пробелы, закодированные как знаки плюс (+). Он кодируется так же, как кодируются опубликованные данные из WWW-формы, так же, как в типе носителя application / x-www-form-urlencoded. Это отличается от кодировки »RFC 1738 (см. Rawurlencode ()) тем, что по историческим причинам пробелы кодируются как знаки плюс (+).

rawurlencode () :

Возвращает строку, в которой все не алфавитно-цифровые символы, кроме -_. были заменены знаком процента (%), за которым следуют две шестнадцатеричные цифры. Это кодировка, описанная в »RFC 1738 для защиты буквенных символов от интерпретации в качестве специальных разделителей URL-адресов и для защиты URL-адресов от искажения средствами передачи с преобразованиями символов (например, в некоторых системах электронной почты).

Эти два очень похожи, но последний (rawurlencode) заменит пробелы на «%» и две шестнадцатеричные цифры, что подходит для кодирования паролей и т. Д., Где «+» не является, например:

echo '<a href="ftp://user:', rawurlencode('foo @+%/'),
     '@ftp.example.com/x.txt">';
//Outputs <a href="ftp://user:foo%20%40%2B%25%2F@ftp.example.com/x.txt">

2
ОП спрашивает, как узнать, что и когда использовать. Знание того, что каждый из них делает с пробелами, не помогает ОП принять решение, если он не знает важности различных возвращаемых значений.
Dotancohen

5

1. Какие именно различия и

Разница лишь в способе обработки пространств:

urlencode - на основе унаследованной реализации преобразует пробелы в +

rawurlencode - на основе RFC 1738 переводит пробелы в% 20

Причина различия заключается в том, что + зарезервирован и действителен (не закодирован) в URL.

2. что является предпочтительным?

Мне бы очень хотелось увидеть некоторые причины для выбора одного над другим ... Я хочу иметь возможность просто выбрать один и использовать его вечно с наименьшим количеством суеты.

Справедливости ради, у меня есть простая стратегия, которой я придерживаюсь при принятии этих решений, которой я поделюсь с вами в надежде, что она может помочь.

Я думаю, что это была спецификация HTTP / 1.1 RFC 2616, которая требовала « толерантных приложений »

Клиенты ДОЛЖНЫ быть терпимы при разборе строки состояния, а серверы - при обработке строки запроса.

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

Поэтому я советую использовать его rawurlencodeдля создания совместимых со стандартами строк в кодировке RFC 1738 и использовать urldecodeдля обеспечения обратной совместимости и приспособления к чему-либо, что вам может потребоваться.

Теперь вы можете просто поверить мне на слово, но давайте докажем, что мы ...

php > $url = <<<'EOD'
<<< > "Which, % of Alice's tasks saw $s @ earnings?"
<<< > EOD;
php > echo $url, PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > echo urlencode($url), PHP_EOL;
%22Which%2C+%25+of+Alice%27s+tasks+saw+%24s+%40+earnings%3F%22
php > echo rawurlencode($url), PHP_EOL;
%22Which%2C%20%25%20of%20Alice%27s%20tasks%20saw%20%24s%20%40%20earnings%3F%22
php > echo rawurldecode(urlencode($url)), PHP_EOL;
"Which,+%+of+Alice's+tasks+saw+$s+@+earnings?"
php > // oops that's not right???
php > echo urldecode(rawurlencode($url)), PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > // now that's more like it

Похоже, что PHP имел в виду именно это, хотя я никогда не сталкивался с тем, кто отказывается от любого из этих двух форматов, я не могу придумать более эффективную стратегию, чтобы принять ее как стратегию де-факто, не так ли?

NJoy!


4

urlencode : отличается от кодировки »RFC 1738 (см. rawurlencode ()) тем, что по историческим причинам пробелы кодируются как знаки плюс (+).


2

Пробелы, закодированные как %20против+

Самая большая причина, которую я видел, чтобы использовать rawurlencode()в большинстве случаев, состоит в том, что urlencodeкодирует текстовые пространства как +(знаки плюс), где rawurlencodeкодирует их как обычно видимый %20:

echo urlencode("red shirt");
// red+shirt

echo rawurlencode("red shirt");
// red%20shirt

Я специально видел определенные конечные точки API, которые принимают закодированные текстовые запросы, ожидающие %20пробела и, как результат, потерпели неудачу, если вместо них использовался знак плюс. Очевидно, что это будет отличаться между реализациями API, и ваш пробег может отличаться.


1

Я считаю, что urlencode для параметров запроса, тогда как rawurlencode для сегментов пути. Это в основном связано с %20сегментами пути и +параметрами запроса. Посмотрите этот ответ, который говорит о пробелах: когда кодировать пробел в плюс (+) или% 20?

Однако %20теперь он работает и с параметрами запроса, поэтому rawurlencode всегда безопаснее. Однако знак «плюс» имеет тенденцию использоваться там, где имеет значение пользовательский опыт редактирования и удобочитаемость параметров запроса.

Обратите внимание, что это означает, rawurldecodeчто не декодировать +в пробелы ( http://au2.php.net/manual/en/function.rawurldecode.php ). Вот почему $ _GET всегда автоматически пропускается urldecode, что означает, что +и%20 оба декодированные в пространствах.

Если вы хотите, чтобы кодирование и декодирование были согласованы между входами и выходами, и вы выбрали всегда использовать, +а не %20для параметров запроса, тоurlencode это хорошо для параметров запроса (ключ и значение).

Вывод:

Сегменты пути - всегда используйте rawurlencode / rawurldecode

Параметры запроса - для декодирования всегда используйте urldecode (выполняется автоматически), для кодирования подойдет и rawurlencode, или urlencode, просто выберите один из них для согласованности, особенно при сравнении URL-адресов.


0

простой * rawurlencode путь - путь это часть перед "?" - пробелы должны быть закодированы как% 20 * urlencode строки запроса - Строка запроса является частью после "?" -пространства лучше кодируются как "+" = rawurlencode в целом более совместим

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.