Кодировать 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 на этой второй строке?

Ответ 1

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

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

Ответ 2

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

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

  • encodeURI() не будет кодироваться: [email protected]#$&*()=:/,;?+'

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

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

Смотрите вопрос о переполнении стека Лучшая практика: escape или encodeURI/encodeURIComponent для дальнейшего обсуждения.

Ответ 3

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

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

Ответ 4

Лучший ответ - использовать 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}';

Ответ 5

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

$.param({a:"1=2", b:"Test 1"}) // gets a=1%3D2&b=Test+1

Ответ 6

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

encodeURI()

и

encodeURIComponent()

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

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

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

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

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

Ответ 7

Метод codedeURIComponent() - это путь.

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', '+');
}

Ответ 8

Аналогичная вещь, которую я пробовал с помощью обычного javascript

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

Ответ 9

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

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

encodeURI("abc%20xyz 123")            //   wrong: "abc%2520xyz%20123"
encodeURI(decodeURI("abc%20xyz 123")) // correct: "abc%20xyz%20123"

Ответ 10

Ничего не работало для меня. Все, что я видел, это 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;
            }
        }
    });
});

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

Ответ 11

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

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

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

Ответ 12

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

    var url = $(location).attr('href'); //get current url
    //OR
    var url = 'folder/index.html?param=#23dd&noob=yes'; //or specify one

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

Ответ 13

Вы можете использовать библиотеку 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

Ответ 14

Вот ЖИВОЙ 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>

Ответ 15

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

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