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

13 ответов


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

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

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

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

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

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

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

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


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

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


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

encodeURIComponent(value).replace(/%20/g,'+');

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

Примечание: вы используете encodeURIComponent для значения на строку запроса (не поля/значение имена и, безусловно,не весь URL). Если вы сделаете это по-другому, он не будет кодировать символы, такие как=,?,&, возможно, оставляя строку запроса открытой.

пример:

const escapedValue = encodeURIComponent(value).replace(/%20/g,'+');
const url = 'http://example.com/?myKey=' + escapedValue;

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

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

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

encodeURI()

и

encodeURIComponent()

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

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

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

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

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


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(/!/g, '%21')
    .replace(/'/g, '%27')
    .replace(/\(/g, '%28')
    .replace(/\)/g, '%29')
    .replace(/\*/g, '%2A')
    .replace(/%20/g, '+');
}

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

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

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

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

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

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

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


кодировать строку 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

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


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

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

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

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

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

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

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

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

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

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

имейте в виду, что не передавайте весь URL (включая scheme, e.g 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 что косые черты foward ( / ) также преобразуются в специальные символы. Это приведет к тому, что URL-адрес больше не будет функционировать должным образом.

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

  1. encodeURIComponent на определенной части URL-адреса, который вы хотите кодировать.
  2. encodeURI на весь URL, который вы хотите закодировать.