Codificare l'URL in JavaScript?


2470

Come si codifica in modo sicuro un URL utilizzando JavaScript in modo che possa essere inserito in una stringa GET?

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

Presumo che sia necessario codificare la myUrlvariabile su quella seconda riga?


22
Prova a esaminare encodeURI () e decodeURI () .
Zack The Human,


1
Puoi usare questo strumento qui: phillihp.com/toolz/url-encode-decode
phillihp

2
encodeURIComponent ()
Andrew

Risposte:


2791

Dai un'occhiata alla funzione integrata encodeURIComponent (str) e encodeURI (str) .
Nel tuo caso, questo dovrebbe funzionare:

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

12
Che ne dici di aggiungere la spiegazione fornita da @cms? escapeè anche un'opzione valida.
hitautodestruct,

11
secondo @CMS encodeURInon è veramente sicuro per la codifica URL.
Ifnot

13
@AnaelFavre perché è destinata a codificare l'intero URL, che non consente caratteri quali :, /, @ecc Questi 2 metodi non sono da utilizzare intercambiabili, è necessario sapere che cosa si codifica per utilizzare il metodo giusto.
Buu Nguyen,


Come menzionato in un'altra risposta in questa pagina , questo sito descrive in dettaglio i motivi per utilizzare questo metodo
Brad Parks,

1522

Hai tre opzioni:

  • escape() non codificherà: @*/+

  • encodeURI() non codificherà: ~!@#$&*()=:/,;?+'

  • encodeURIComponent() non codificherà: ~!*()'

Ma nel tuo caso, se vuoi passare un URL a un GETparametro di un'altra pagina, dovresti usare escapeo encodeURIComponent, ma non encodeURI.

Vedi domanda Stack Overflow Best practice: escape, o encodeURI / encodeURIComponent per ulteriori discussioni.


76
La codifica dei caratteri utilizzata con escape è variabile. Stick con encodeURI e encodeURIComponent, che utilizzano UTF-8.
Erickson,

6
Stai attento. Quella fuga converte i caratteri non ASCII nelle sue sequenze di fuga Unicode, come %uxxx.
Opteronn,

4
Sto usando encodeURIComponent e notando che non codificherà i caratteri pipe |
Kevinevler,

15
@kevzettler - perché dovrebbe farlo? Le pipe non sono di importanza semantica in un URI.
Nickf

4
@GiovanniP: persone che consentono l'inserimento di caratteri tedeschi, francesi, giapponesi, cinesi e arabi e passano questi parametri tramite GET o POST.
Tseng,

180

Resta con encodeURIComponent(). La funzione encodeURI()non si preoccupa di codificare molti caratteri che hanno un'importanza semantica negli URL (ad es. "#", "?" E "&"). escape()è obsoleto e non si preoccupa di codificare i caratteri "+", che verranno interpretati come spazi codificati sul server (e, come sottolineato da altri qui, non codificano correttamente i caratteri non ASCII con codifica URL).

C'è una bella spiegazione della differenza tra encodeURI()eencodeURIComponent() altrove. Se si desidera codificare qualcosa in modo che possa essere incluso in modo sicuro come componente di un URI (ad es. Come parametro della stringa di query), si desidera utilizzare encodeURIComponent().


83

La migliore risposta è quella di utilizzare encodeURIComponentin valori nella stringa di query (e non altrove).

Tuttavia, trovo che molte API vogliano sostituire "" con "+", quindi ho dovuto usare quanto segue:

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

escapeè implementato in modo diverso nei diversi browser e encodeURInon codifica molti caratteri (come # e anche /) - è fatto per essere utilizzato su un URI / URL completo senza romperlo - che non è molto utile o sicuro.

E come sottolinea @Jochem di seguito, potresti voler utilizzare encodeURIComponent()un (ogni) nome di cartella, ma per qualsiasi motivo queste API non sembrano volere +nei nomi di cartelle, quindi il vecchio encodeURIComponentfunziona alla grande.

Esempio:

const escapedValue = encodeURIComponent(value).replace('%20','+');
const escapedFolder = encodeURIComponent('My Folder'); // no replace
const url = `http://example.com/${escapedFolder}/?myKey=${escapedValue}`;

22
Tieni presente che devi sostituire% 20 con i simboli + solo dopo il primo punto interrogativo (che è la parte "query" dell'URL). Diciamo che voglio navigare http://somedomain/this dir has spaces/info.php?a=this has also spaces. Dovrebbe essere convertito in: http://somedomain/this%20dir%20has%spaces/info.php?a=this%20has%20also%20spacesma molte implementazioni consentono di sostituire "% 20" nella stringa di query con "+". Tuttavia, non è possibile sostituire '% 20' con '+' nella sezione del percorso dell'URL, ciò comporterà un errore Not Found a meno che non si disponga di una directory con un +anziché uno spazio.
Jochem Kuijpers,

@Jochem Kuijpers, sicuramente, non inseriresti "+" in una directory. Lo applicherei solo ai valori dei parametri di query stessi (o chiavi se necessario), non all'intero URL o persino all'intera stringa di query.
Ryan Taylor,

Sostituirei in valore piuttosto che nel risultato della codifica
njzk2

1
@ njzk2 purtroppo encodeURIComponent('+')ti darebbe %2B, quindi dovresti usare due espressioni regolari ... che suppongo sia un po 'il motivo per cui funziona, perché' + 'sono' 'sono codificati in modo diverso alla fine.
Ryan Taylor,

Non c'è motivo di tradurre% 20 in "+". La sequenza di escape valida per lo spazio ASCII è% 20, non "+" che non è menzionato in RFC 3986 ( tools.ietf.org/html/rfc3986 ). "+" è stato utilizzato negli anni '90; ora è obsoleto ed è supportato solo per motivi legacy. Non usarlo.
Xhienne,

40

Se stai usando jQuery andrei per il $.parammetodo. URL codifica i valori di un oggetto mappando i campi, che è più facile da leggere rispetto alla chiamata di un metodo di escape su ciascun valore.

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

Penso che l'esempio fornito sia sufficiente. Se hai bisogno di maggiori informazioni su $ .param
Maksym Kozlenko,

Quasi tutti usano jQuery e mi sento davvero più a mio agio con questo invece del componente encoreURIC
Cyril Duchon-Doris

12

encodeURIComponent () è la strada da percorrere.

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

MA dovresti tenere a mente che ci sono piccole differenze rispetto alla versione php urlencode()e come citato da @CMS, non codificherà ogni carattere. I ragazzi su http://phpjs.org/functions/urlencode/ hanno reso js equivalente a 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', '+');
}

10

Per codificare un URL, come è stato detto prima, hai due funzioni:

encodeURI()

e

encodeURIComponent()

La ragione per cui entrambe esistono è che la prima conserva l'URL con il rischio di lasciare troppe cose senza caratteri di escape, mentre la seconda codifica per tutto ciò che è necessario.

Con il primo, potresti copiare l'URL appena salvato nella barra degli indirizzi (ad esempio) e funzionerebbe. Tuttavia, i "&" senza caratteri di escape interferirebbero con i delimitatori di campo, i "=" interferirebbero con i nomi e i valori dei campi e i "+" sembrerebbero spazi. Ma per dati semplici quando vuoi preservare la natura dell'URL di ciò che stai scappando, questo funziona.

Il secondo è tutto ciò che devi fare per assicurarti che nulla nella tua stringa interferisca con un URL. Lascia diversi caratteri non importanti senza caratteri di escape in modo che l'URL rimanga il più leggibile possibile senza interferenze. Un URL codificato in questo modo non funzionerà più come un URL senza annullarlo.

Quindi, se puoi prendere il tempo, vuoi sempre usare encodeURIComponent () - prima di aggiungere coppie nome / valore codifica sia il nome che il valore usando questa funzione prima di aggiungerlo alla stringa di query.

Sto attraversando un periodo difficile con le ragioni per usare encodeURI () - lo lascerò alle persone più intelligenti.


5

Tipo simile di cose che ho provato con javascript normale

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

5

Modo elegante

Secondo la mia modesta opinione, il modo più elegante per codificare i parametri di query è creare un oggetto con parametri come

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

e poi codificalo usando:

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

come indicato in questa risposta: https://stackoverflow.com/a/53171438/7284582


4

Per evitare la doppia codifica è una buona idea decodificare l'URL prima della codifica (ad esempio se si tratta di URL immessi dall'utente, che potrebbero essere già codificati).

Diciamo che abbiamo abc%20xyz 123come input (uno spazio è già codificato):

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

4

Cos'è la codifica URL:

Un URL deve essere codificato quando sono presenti caratteri speciali all'interno dell'URL. Per esempio:

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

In questo esempio possiamo osservare che tutti i caratteri tranne la stringa notEncodedsono codificati con segni%. La codifica URL è anche nota come codifica percentuale perché sfugge a tutti i caratteri speciali con una%. Quindi dopo questo segno% ogni carattere speciale ha un codice univoco

Perché abbiamo bisogno della codifica URL:

Alcuni caratteri hanno un valore speciale in una stringa URL. Ad esempio, il? carattere indica l'inizio di una stringa di query. Per individuare con successo una risorsa sul web, è necessario distinguere tra quando un carattere è inteso come parte di una stringa o parte della struttura dell'URL.

Come possiamo ottenere la codifica URL in JS:

JS offre una serie di funzioni di utilità integrate che possiamo usare per codificare facilmente gli URL. Queste sono due opzioni convenienti:

  1. encodeURIComponent(): Accetta un componente di un URI come argomento e restituisce la stringa URI codificata.
  2. encodeURI(): Accetta un URI come argomento e restituisce la stringa URI codificata.

Esempio e avvertenze:

Fai attenzione a non passare l'intero URL (incluso lo schema, ad esempio https: //) in encodeURIComponent(). Questo può effettivamente trasformarlo in un URL non funzionale. Per esempio:

// 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"));

Possiamo osservare che abbiamo inserito l'intero URL in modo encodeURIComponentche anche le barre in avanti (/) vengano convertite in caratteri speciali. Ciò farà sì che l'URL non funzioni più correttamente.

Pertanto (come suggerisce il nome) utilizzare:

  1. encodeURIComponent su una determinata parte di un URL che si desidera codificare.
  2. encodeURI su un intero URL che desideri codificare.

3

Niente ha funzionato per me. Tutto quello che stavo vedendo era l'HTML della pagina di accesso, che tornava sul lato client con il codice 200. (302 all'inizio, ma la stessa richiesta Ajax caricava la pagina di accesso all'interno di un'altra richiesta Ajax, che doveva essere un reindirizzamento piuttosto che un caricamento normale testo della pagina di accesso).

Nel controller di accesso, ho aggiunto questa riga:

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

E nel gestore globale Ajax, ho fatto questo:

$(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;
            }
        }
    });
});

Ora non ho alcun problema e funziona come un fascino.


2

Codifica stringa URL

    var url = $ ( posizione ). attr ( 'href' ); // get url corrente // OR var url = 'folder / index.html? param = # 23dd & noob = yes' ; // o specificarne uno 
    
      

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

Ecco una DEMO LIVE di encodeURIComponent()e decodeURIComponent()funzioni integrate di 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>

1

Puoi usare la libreria esapi e codificare il tuo url usando la seguente funzione. La funzione assicura che '/' non vada perso per la codifica mentre il resto del contenuto del testo viene codificato:

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

Utilizzare la fixedEncodeURIComponentfunzione per rispettare rigorosamente RFC 3986 :

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

1

Non dovresti usare encodeURIComponent()direttamente.

Dai un'occhiata a RFC3986: Uniform Resource Identifier (URI): sintassi generica

sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Lo scopo dei caratteri riservati è di fornire un set di caratteri delimitanti che siano distinguibili da altri dati all'interno di un URI.

Questi caratteri riservati dalla definizione URI in RFC3986 NON SONO sfuggiti a encodeURIComponent().

Documenti Web MDN: encodeURIComponent ()

Per essere più rigorosi nell'aderire a RFC 3986 (che riserva!, ', (,) E *), anche se questi caratteri non hanno usi di delimitazione URI formalizzati, è possibile utilizzare in sicurezza:

Utilizzare la funzione MDN Web Docs ...

function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.