Кодировать URL в JavaScript?

Как безопасно кодировать URL-адрес с помощью JavaScript, чтобы его можно было вставить в строку GET?

var myUrl = "http://example.com/index.html?param=1&anotherParam=2";
var myOtherUrl = "http://example.com/index.html?url=" + myUrl;

Я предполагаю, что вам нужно закодировать myUrlпеременную во второй строке?

2.12.2008 02:37:08
Попробуйте заглянуть в encodeURI () и decodeURI () .
Zack The Human 2.12.2008 02:39:29
Yanni 30.06.2011 16:40:38
Вы можете использовать этот инструмент здесь: phillihp.com/toolz/url-encode-decode
phillihp 18.09.2012 02:13:19
encodeURIComponent ()
Andrew 2.03.2018 18:52:42
16 ОТВЕТОВ
РЕШЕНИЕ

Проверьте встроенную функцию encodeURIComponent (str) и encodeURI (str) .
В вашем случае это должно работать:

var myOtherUrl = 
       "http://example.com/index.html?url=" + encodeURIComponent(myUrl);
2776
22.04.2019 07:02:16
Как насчет добавления объяснения, которое дал @cms? escapeтакже является допустимым вариантом.
hitautodestruct 28.10.2012 11:36:53
в соответствии с @CMS encodeURIне совсем безопасен для кодирования URL.
Ifnot 1.03.2013 16:35:54
@AnaelFavre, потому что он предназначен для кодирования всего URL, который не допускает использование таких символов, как :, /и @т. Д. Эти 2 метода не должны использоваться взаимозаменяемо, вы должны знать, что вы кодируете, чтобы использовать правильный метод.
Buu Nguyen 6.03.2013 19:32:38
Как упомянуто в другом ответе на этой странице , этот сайт хорошо описывает причину использования этого метода
Brad Parks 6.05.2016 13:07:01

У вас есть три варианта:

  • escape() не будет кодировать: @*/+

  • encodeURI() не будет кодировать: ~!@#$&*()=:/,;?+'

  • encodeURIComponent() не будет кодировать: ~!*()'

Но в вашем случае, если вы хотите передать URL в GETпараметр другой страницы, вы должны использовать escapeили encodeURIComponent, но не использовать encodeURI.

См. Вопрос «Переполнение стека». Рекомендации : escape или encodeURI / encodeURIComponent для дальнейшего обсуждения.

1512
23.05.2017 12:02:48
Кодировка символов, используемая с escape, является переменной. Палка с encodeURI и encodeURIComponent, которые используют UTF-8.
erickson 2.12.2008 04:55:45
Быть осторожен. Этот escape преобразует не-ASCII символы в его escape-последовательности Unicode, например %uxxx.
opteronn 5.03.2010 20:10:15
Я использую encodeURIComponent и заметил, что он не будет кодировать символы канала |
kevzettler 30.01.2011 05:05:08
@kevzettler - зачем это делать? Каналы не имеют семантической важности в URI.
nickf 31.01.2011 11:36:58
@GiovanniP: Люди, которые допускают ввод немецких, французских, японских, китайских, арабских символов и передают параметры тезисов через GET или POST.
Tseng 4.09.2013 14:43:55

Придерживайтесь encodeURIComponent(). Функция encodeURI()не пытается кодировать много символов, имеющих семантическое значение в URL (например, «#», «?» И «&»). escape()устарела и не имеет смысла кодировать символы «+», которые будут интерпретироваться как закодированные пробелы на сервере (и, как указано другими здесь, неправильно кодирует URL-адреса не-ASCII-символов).

Есть хорошее объяснение разницы между encodeURI()и вencodeURIComponent() других местах. Если вы хотите что-то кодировать, чтобы его можно было безопасно включить в качестве компонента URI (например, в качестве параметра строки запроса), вы хотите использовать его encodeURIComponent().

179
23.05.2017 12:02:48

У меня ничего не получалось. Все, что я видел, это HTML-код страницы входа, возвращаясь на клиентскую сторону с кодом 200. (Сначала 302, но тот же Ajax-запрос, загружающий страницу входа в другой Ajax-запрос, который должен был быть перенаправлением, а не простой загрузкой текст страницы входа).

В контроллере входа я добавил эту строку:

Response.Headers["land"] = "login";

И в глобальном обработчике Ajax я сделал это:

$(function () {
    var $document = $(document);
    $document.ajaxSuccess(function (e, response, request) {
        var land = response.getResponseHeader('land');
        var redrUrl = '/login?ReturnUrl=' + encodeURIComponent(window.location);
        if(land) {
            if (land.toString() === 'login') {
                window.location = redrUrl;
            }
        }
    });
});

Теперь у меня нет никаких проблем, и это работает как шарм.

3
3.01.2013 07:31:07

Лучший ответ заключается в использовании encodeURIComponentна значениях в строке запроса (и нигде больше).

Тем не менее, я считаю, что многие API хотят заменить "" на "+", поэтому мне пришлось использовать следующее:

const value = encodeURIComponent(value).replace('%20','+');
const url = 'http://example.com?lang=en&key=' + value

escapeреализован по-разному в разных браузерах и encodeURIне кодирует много символов (например, # и даже /) - он предназначен для использования с полным URI / URL, не нарушая его - что не очень полезно и не безопасно.

И, как указывает @Jochem ниже, вы можете использовать имя encodeURIComponent()(каждой) папки, но по какой-то причине эти API не нужны +в именах папок, поэтому старые приложения encodeURIComponentпрекрасно работают.

Пример:

const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;
83
21.08.2019 16:11:35
Обратите внимание, что вы должны заменять% 20 ​​на символы + только после первого вопросительного знака (который является частью URL-адреса запроса). Допустим, я хочу просмотреть http://somedomain/this dir has spaces/info.php?a=this has also spaces. Его следует преобразовать в: http://somedomain/this%20dir%20has%spaces/info.php?a=this%20has%20also%20spacesно многие реализации допускают замену «% 20» в строке запроса на «+». Тем не менее, вы не можете заменить «% 20» на «+» в разделе пути URL-адреса, это приведет к ошибке «Не найден», если у вас нет каталога с +пробелом.
Jochem Kuijpers 20.01.2013 01:08:13
@Jochem Kuijpers, определенно, вы бы не поместили «+» в каталог. Я бы применил это только к самим значениям параметров запроса (или ключам, если необходимо), а не ко всему URL или даже всей строке запроса.
Ryan Taylor 19.07.2013 22:16:32
Я бы заменил в значении, а не в результате кодировки
njzk2 2.06.2014 18:11:51
@ njzk2, к сожалению encodeURIComponent('+'), даст вам %2B, так что вам придется использовать два регулярных выражения ... что, я полагаю, почему-то так работает, потому что '+' are '' в конце кодируются по-разному.
Ryan Taylor 2.06.2014 18:17:27
Нет смысла переводить% 20 ​​в "+". Допустимая escape-последовательность для пространства ASCII:% 20, а не «+», что не упомянуто в RFC 3986 ( tools.ietf.org/html/rfc3986 ). «+» использовался в 1990-х годах; сейчас он устарел и поддерживается только по старым причинам. Не используйте это.
xhienne 26.03.2019 12:25:06

Если вы используете JQuery, я бы пошел на $.paramметод. Он URL кодирует поля сопоставления объектов со значениями, которые легче читать, чем вызывать метод escape для каждого значения.

$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1
40
25.05.2014 22:55:43
Я думаю, что приведенный пример является достаточным. Если вам нужна дополнительная информация о $ .param на api.jquery.com/jquery.param
Maksym Kozlenko 10.09.2015 10:21:52
Почти все используют jQuery, и я действительно чувствую себя более комфортно с этим, а не с компонентом uRIComponent
Cyril Duchon-Doris 4.01.2017 16:36:08

Подобные вещи я пробовал с обычным JavaScript

function fixedEncodeURIComponent(str){
     return encodeURIComponent(str).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
}
5
14.05.2013 08:01:41

Кодировать строку URL

    var url = $ ( местоположение ). attr ( 'href' ); // получить текущий URL // ИЛИ var url = 'folder / index.html? param = # 23dd & noob = yes' ; // или указать один 
    
      

var encodedUrl = encodeURIComponent(url); console.log(encodedUrl); //outputs folder%2Findex.html%3Fparam%3D%2323dd%26noob%3Dyes for more info go http://www.sitepoint.com/jquery-decode-url-string
2
10.09.2015 06:41:37

encodeURIComponent () - это путь.

var myOtherUrl = "http://example.com/index.html?url=" + encodeURIComponent(myUrl);

НО вы должны иметь в виду, что есть небольшие отличия от версии php, urlencode()и, как упоминалось в @CMS, она не будет кодировать каждый символ. Ребята на http://phpjs.org/functions/urlencode/ сделали js эквивалентным phpencode():

function urlencode(str) {
  str = (str + '').toString();

  // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
  // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
  return encodeURIComponent(str)
    .replace('!', '%21')
    .replace('\'', '%27')
    .replace('(', '%28')
    .replace(')', '%29')
    .replace('*', '%2A')
    .replace('%20', '+');
}
12
21.08.2019 16:21:17

Вы можете использовать библиотеку esapi и кодировать свой URL, используя функцию ниже. Функция гарантирует, что «/» не будут потеряны для кодирования, в то время как остальная часть текстового содержимого закодирована:

function encodeUrl(url)
{
    String arr[] = url.split("/");
    String encodedUrl = "";
    for(int i = 0; i<arr.length; i++)
    {
        encodedUrl = encodedUrl + ESAPI.encoder().encodeForHTML(ESAPI.encoder().encodeForURL(arr[i]));
        if(i<arr.length-1) encodedUrl = encodedUrl + "/";
    }
    return url;
}

https://www.owasp.org/index.php/ESAPI_JavaScript_Readme

1
17.07.2019 08:37:01

Чтобы предотвратить двойное кодирование, рекомендуется декодировать URL-адрес перед кодированием (например, если вы имеете дело с введенными пользователем URL-адресами, которые могут быть уже закодированы).

Допустим, мы имеем в abc%20xyz 123качестве входных данных (один пробел уже закодирован):

encodeURI("abc%20xyz 123")            //   wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"
4
5.01.2017 18:49:48

Для кодирования URL, как уже было сказано, у вас есть две функции:

encodeURI()

а также

encodeURIComponent()

Причина обоих заключается в том, что первый сохраняет URL-адрес с риском оставить слишком много вещей без изменений, а второй кодирует все необходимое.

С первым вы можете скопировать недавно экранированный URL в адресную строку (например), и он будет работать. Однако ваши неэкранированные '& будут мешать разделителям полей,' = 'будут влиять на имена и значения полей, а' + 'будут выглядеть как пробелы. Но для простых данных, когда вы хотите сохранить природу URL того, что вы избегаете, это работает.

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

Поэтому, если вы можете потратить время, вы всегда хотите использовать encodeURIComponent () - перед добавлением пар имя / значение кодируйте и имя, и значение, используя эту функцию, перед добавлением его в строку запроса.

Мне трудно найти причины для использования encodeURI () - я оставлю это более умным людям.

10
26.01.2017 21:31:43

Что такое кодировка URL:

URL-адрес должен быть закодирован, если в нем есть специальные символы. Например:

console.log(encodeURIComponent('?notEncoded=&+'));

В этом примере мы можем наблюдать, что все символы, кроме строки notEncoded, кодируются знаками%. Кодировка URL также называется процентной кодировкой, поскольку она экранирует все специальные символы с помощью%. Затем после этого знака% каждый специальный символ имеет уникальный код

Зачем нам нужна кодировка URL:

Некоторые символы имеют специальное значение в строке URL. Например,? символ обозначает начало строки запроса. Чтобы успешно найти ресурс в сети, необходимо различать, когда символ подразумевается как часть строки или часть структуры URL.

Как мы можем добиться кодирования URL в JS:

JS предлагает набор встроенных служебных функций, которые мы можем использовать для простого кодирования URL. Это два удобных варианта:

  1. encodeURIComponent(): Принимает компонент URI в качестве аргумента и возвращает закодированную строку URI.
  2. encodeURI(): Принимает URI в качестве аргумента и возвращает закодированную строку URI.

Пример и предостережения:

Помните, что не следует передавать весь URL (включая схему, например, https: //) в encodeURIComponent(). Это может фактически превратить его в не функциональный URL. Например:

// for a whole URI don't use encodeURIComponent it will transform
// the / characters and the URL won't fucntion properly
console.log(encodeURIComponent("http://www.random.com/specials&char.html"));

// instead use encodeURI for whole URL's
console.log(encodeURI("http://www.random.com/specials&char.html"));

Мы можем наблюдать, что мы помещаем весь URL в encodeURIComponentтом, что косые черты (/) также преобразуются в специальные символы. Это приведет к тому, что URL больше не будет работать должным образом.

Поэтому (как следует из названия) используйте:

  1. encodeURIComponent на определенной части URL, который вы хотите кодировать.
  2. encodeURI на весь URL, который вы хотите закодировать.
4
23.09.2018 08:35:26

Вот ЖИВОЙ DEMO из encodeURIComponent()и decodeURIComponent()JS встроенных функций:

<!DOCTYPE html>
<html>
  <head>
    <style>
      textarea{
        width:30%;
        height:100px;
      }
    </style>
    <script>
      // encode string to base64
      function encode()
      {
        var txt = document.getElementById("txt1").value;
        var result = btoa(txt);
        document.getElementById("txt2").value = result;
      }
      // decode base64 back to original string
      function decode()
      {
        var txt = document.getElementById("txt3").value;
        var result = atob(txt);
        document.getElementById("txt4").value = result;
      }
    </script>
  </head>
  <body>
    <div>
      <textarea id="txt1">Some text to decode
      </textarea>
    </div>
    <div>
      <input type="button" id="btnencode" value="Encode" onClick="encode()"/>
    </div>
    <div>
      <textarea id="txt2">
      </textarea>
    </div>
    <br/>
    <div>
      <textarea id="txt3">U29tZSB0ZXh0IHRvIGRlY29kZQ==
      </textarea>
    </div>
    <div>
      <input type="button" id="btndecode" value="Decode" onClick="decode()"/>
    </div>
    <div>
      <textarea id="txt4">
      </textarea>
    </div>
  </body>
</html>
2
9.02.2019 10:26:42

Используйте fixedEncodeURIComponentфункцию для строгого соответствия RFC 3986 :

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}
1
5.10.2019 20:48:17

Элегантный способ

По моему скромному мнению, самый элегантный способ кодирования параметров запроса - создать объект с такими параметрами, как

const queryParams = { param1: 'value1', param2: 'value2' }

и затем закодируйте его, используя:

const queryString = new URLSearchParams(queryParams).toString()

как упоминалось в этом ответе: https://stackoverflow.com/a/53171438/7284582

2
9.01.2020 13:59:38