web-dev-qa-db-fra.com

Encoder l'URL en JavaScript?

Comment coder en toute sécurité une URL à l'aide de JavaScript, de sorte qu'elle puisse être insérée dans une chaîne GET?

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

Je suppose que vous devez encoder la variable myUrl sur cette deuxième ligne?

2236
nickf

Découvrez les fonctions intégrées encodeURIComponent(str) et encodeURI(str).
Dans votre cas, cela devrait fonctionner:

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

Vous avez trois options:

  • escape() n'encodera pas: @*/+

  • encodeURI() n'encodera pas: ~!@#$&*()=:/,;?+'

  • encodeURIComponent() n'encodera pas: ~!*()'

Mais dans votre cas, si vous voulez passer un URL dans un paramètre GET d’une autre page, vous devez utiliser escape ou encodeURIComponent, mais pas encodeURI.

Voir la question relative au débordement de pile Meilleure pratique: échapper ou encoderURI/encoderURIComponent pour une analyse plus approfondie.

1438
CMS

Stick avec encodeURIComponent() . La fonction encodeURI() ne s’embête pas à coder de nombreux caractères ayant une importance sémantique dans les URL (par exemple, "#", "?" Et "&"). escape() est obsolète et ne s'embarrasse pas de coder les caractères "+", qui seront interprétés comme des espaces codés sur le serveur (et, comme souligné par d'autres ici, ne codent pas correctement les caractères non-ASCII par URL) .

Il existe une explication de Nice de la différence entre encodeURI() et encodeURIComponent() ailleurs. Si vous souhaitez encoder quelque chose de sorte qu'il puisse être inclus en toute sécurité en tant que composant d'un URI (par exemple, en tant que paramètre de chaîne de requête), vous souhaitez utiliser encodeURIComponent().

165
Mike Brennan

Personnellement, je trouve que beaucoup d’API veulent remplacer "" par "+" et j’utilise donc ce qui suit:

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

escape est implémenté différemment dans différents navigateurs et encodeURI ne code pas la plupart des caractères fonctionnels dans un URI (comme # et même /) - il est conçu pour être utilisé sur un URI/URL complet sans le rompre.

NOTE: vous utilisez encodeURIComponent pour values ​​ dans la chaîne query (pas les noms de champs/valeurs et certainement pas l'URL complète). Si vous le faites d'une autre manière, les caractères tels que =,?, & Ne seront pas encodés, ce qui risquerait de laisser votre chaîne de requête exposée.

Exemple:

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

Si vous utilisez jQuery, je choisirais la méthode $.param . Cette URL code les valeurs des champs de mappage d'un objet, ce qui est plus facile à lire que d'appeler une méthode d'échappement pour chaque valeur.

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

Comme il a été dit précédemment, pour encoder une URL, vous avez deux fonctions:

encodeURI()

et 

encodeURIComponent()

La raison en est que le premier conserve l’URL avec le risque de laisser trop de choses non échappées, tandis que le second encode tout ce qui est nécessaire.

Avec le premier, vous pouvez copier l'URL nouvellement échappée dans la barre d'adresse (par exemple) et cela fonctionnerait. Cependant, vos '&' non interférés interféreraient avec les délimiteurs de champs, les '=' interféreraient avec les noms et les valeurs de champs et les '+' ressembleraient à des espaces. Mais pour des données simples lorsque vous souhaitez conserver la nature de l'URL de ce que vous échappez, cela fonctionne.

La seconde est tout ce que vous devez faire pour vous assurer que rien dans votre chaîne n’interfère avec une URL. Cela laisse divers caractères sans importance non échappés, de sorte que l'URL reste aussi lisible que possible par l'homme, sans interférence. Une URL encodée de cette manière ne fonctionnera plus comme une URL sans la décomprimer.

Donc, si vous pouvez prendre le temps, vous voulez toujours utiliser encodeURIComponent () - avant d'ajouter des paires nom/valeur, encodez le nom et la valeur à l'aide de cette fonction avant de l'ajouter à la chaîne de requête.

J'ai de la difficulté à trouver des raisons pour utiliser la méthode encodeURI () - je laisserai cela aux personnes les plus intelligentes.

9
Gerard ONeill

encodeURIComponent () est le chemin à parcourir.

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

MAIS vous devez garder à l’esprit qu’il existe de petites différences par rapport à la version php urlencode() et que, comme @CMS l’a mentionné, il ne codera pas tous les caractères. Les gars sur http://phpjs.org/functions/urlencode/ ont rendu js équivalent à 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, '+');
}
8
Adam Fischer

Genre similaire de chose que j'ai essayé avec javascript normal

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

Pour éviter le double encodage, il est conseillé de décoder l'URL avant de l'encoder (si vous traitez avec des URL entrées par l'utilisateur, par exemple, qui sont peut-être déjà encodées).

Disons que nous avons abc%20xyz 123 en entrée (un espace est déjà encodé):

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

Rien n'a fonctionné pour moi. Tout ce que je voyais, c’était le code HTML de la page de connexion, renvoyant du côté du client avec le code 200. (302 au début, mais la même demande Ajax chargeant la page de connexion dans une autre demande Ajax, qui était supposée être une redirection plutôt que texte de la page de connexion).

Dans le contrôleur de connexion, j'ai ajouté cette ligne:

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

Et dans le gestionnaire global Ajax, j'ai fait ceci:

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

Maintenant, je n'ai aucun problème, et cela fonctionne comme un charme.

2
Asif Ashraf

Voici une LIVE DEMO of encodeURIComponent() and decodeURIComponent() JS fonctions intégrées:

<!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>
0
jonathana

Vous pouvez utiliser la bibliothèque esapi et encoder votre URL en utilisant la fonction ci-dessous. La fonction endure que '/' ne soit pas perdu pour l'encodage pendant que le reste du contenu du texte est encodé:

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

0
Mohith Maratt