Question

Lors de l'encodage d'une chaîne de requête à envoyer à un serveur Web - quand utilisez-vous escape() et quand utilises-tu encodeURI() ou encodeURIComponent():

Utilisez l'échappement :

escape("% +&=");

OU

utilisez encodeURI() / encodeURIComponent()

encodeURI("http://www.google.com?var1=value1&var2=value2");

encodeURIComponent("var1=value1&var2=value2");
Était-ce utile?

La solution

escape ()

Ne l'utilisez pas! escape() est défini dans la section B.2.1. 2 évasions et le texte d'introduction de l'annexe B dit:

  

... Toutes les caractéristiques et tous les comportements de langage spécifiés dans la présente annexe ont une ou plusieurs caractéristiques indésirables et, en l'absence d'utilisation héritée du passé, ils seraient supprimés de cette spécification. ...
  ... Les programmeurs ne devraient pas utiliser ou supposer l’existence de ces caractéristiques et comportements lors de l’écriture de nouveau code ECMAScript ....

Comportement:

https://developer.mozilla.org/ en-US / docs / Web / JavaScript / Référence / Global_Objects / escape

Les caractères spéciaux sont codés à l'exception de: @ * _ + -. /

La forme hexadécimale des caractères dont l'unité de code est égale ou inférieure à 0xFF est une séquence d'échappement à deux chiffres: %xx.

Pour les caractères avec une unité de code supérieure, le format à quatre chiffres %uxxxx est utilisé. Ceci n'est pas autorisé dans une chaîne de requête (comme défini dans la RFC3986 ):

query       = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

Un signe de pourcentage n'est autorisé que s'il est directement suivi de deux chiffres hexadécimaux, le pourcentage suivi de u n'est pas autorisé.

encodeURI ()

Utilisez encodeURI lorsque vous souhaitez une URL fonctionnelle. Faites cet appel:

encodeURI("http://www.example.org/a file with spaces.html")

pour obtenir:

http://www.example.org/a%20file%20with%20spaces.html

N'appelez pas encodeURIComponent car cela détruirait l'URL et renverrait

http%3A%2F%2Fwww.example.org%2Fa%20file%20with%20spaces.html

encodeURIComponent ()

Utilisez encodeURIComponent lorsque vous souhaitez coder la valeur d'un paramètre d'URL.

var p1 = encodeURIComponent("http://example.org/?a=12&b=55")

Vous pouvez ensuite créer l'URL dont vous avez besoin:

var url = "http://example.net/?param1=" + p1 + "&param2=99";

Et vous obtiendrez cette URL complète:

http://example.net/?param1=http%3A%2F%2Fexample.org%2F%Ffa%3D12%26b%3D55&param2=99

Notez qu'encodeURIComponent n'échappe pas au caractère '. Un bogue courant consiste à l’utiliser pour créer des attributs HTML tels que href='MyUrl', qui pourraient subir un bogue d’injection. Si vous construisez du code HTML à partir de chaînes, utilisez " au lieu de <=> pour les guillemets d'attributs, ou ajoutez une couche d'encodage supplémentaire (<=> peut être codé sous la forme% 27).

Pour plus d'informations sur ce type d'encodage, vous pouvez consulter: http: //en.wikipedia. org / wiki / Pourcentage d'encodage

Autres conseils

La différence entre encodeURI() et encodeURIComponent() correspond exactement à 11 caractères codés par encodeurURIComponent mais pas par encodeurURI:

.

Tableau avec les dix différences entre encodeURI et encodeURIComponent

J'ai généré ce tableau facilement avec console.table dans Google Chrome avec le code suivant:

.

var arr = [];
for(var i=0;i<256;i++) {
  var char=String.fromCharCode(i);
  if(encodeURI(char)!==encodeURIComponent(char)) {
    arr.push({
      character:char,
      encodeURI:encodeURI(char),
      encodeURIComponent:encodeURIComponent(char)
    });
  }
}
console.table(arr);

J'ai trouvé cet article éclairant: Javascript Madness: analyse de la chaîne de requête

Je l’ai trouvé lorsque j’essayais de comprendre pourquoi le décodageURIComponent ne décodait pas correctement le «+». Voici un extrait:

String:                         "A + B"
Expected Query String Encoding: "A+%2B+B"
escape("A + B") =               "A%20+%20B"     Wrong!
encodeURI("A + B") =            "A%20+%20B"     Wrong!
encodeURIComponent("A + B") =   "A%20%2B%20B"   Acceptable, but strange

Encoded String:                 "A+%2B+B"
Expected Decoding:              "A + B"
unescape("A+%2B+B") =           "A+++B"       Wrong!
decodeURI("A+%2B+B") =          "A+++B"       Wrong!
decodeURIComponent("A+%2B+B") = "A+++B"       Wrong!

encodeURIComponent ne code pas -_.!~*'(), ce qui pose un problème de publication de données sur php dans une chaîne xml.

Par exemple:
<xml><text x="100" y="150" value="It's a value with single quote" /> </xml>

Evasion générale avec encodeURI
%3Cxml%3E%3Ctext%20x=%22100%22%20y=%22150%22%20value=%22It's%20a%20value%20with%20single%20quote%22%20/%3E%20%3C/xml%3E

Comme vous pouvez le constater, les guillemets simples ne sont pas codés. Pour résoudre le problème, j'ai créé deux fonctions pour résoudre le problème dans mon projet, pour URL de codage:

.
function encodeData(s:String):String{
    return encodeURIComponent(s).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}

Pour l'URL de décodage:

function decodeData(s:String):String{
    try{
        return decodeURIComponent(s.replace(/\%2D/g, "-").replace(/\%5F/g, "_").replace(/\%2E/g, ".").replace(/\%21/g, "!").replace(/\%7E/g, "~").replace(/\%2A/g, "*").replace(/\%27/g, "'").replace(/\%28/g, "(").replace(/\%29/g, ")"));
    }catch (e:Error) {
    }
    return "";
}

encodeURI () - la fonction escape () sert à l'échappement javascript, pas à HTTP.

Petit tableau de comparaison Java, JavaScript et PHP.

1. Java URLEncoder.encode (using UTF8 charset)
2. JavaScript encodeURIComponent
3. JavaScript escape
4. PHP urlencode
5. PHP rawurlencode

char   JAVA JavaScript --PHP---
[ ]     +    %20  %20  +    %20
[!]     %21  !    %21  %21  %21
[*]     *    *    *    %2A  %2A
[']     %27  '    %27  %27  %27 
[(]     %28  (    %28  %28  %28
[)]     %29  )    %29  %29  %29
[;]     %3B  %3B  %3B  %3B  %3B
[:]     %3A  %3A  %3A  %3A  %3A
[@]     %40  %40  @    %40  %40
[&]     %26  %26  %26  %26  %26
[=]     %3D  %3D  %3D  %3D  %3D
[+]     %2B  %2B  +    %2B  %2B
[$]     %24  %24  %24  %24  %24
[,]     %2C  %2C  %2C  %2C  %2C
[/]     %2F  %2F  /    %2F  %2F
[?]     %3F  %3F  %3F  %3F  %3F
[#]     %23  %23  %23  %23  %23
[[]     %5B  %5B  %5B  %5B  %5B
[]]     %5D  %5D  %5D  %5D  %5D
----------------------------------------
[~]     %7E  ~    %7E  %7E  ~
[-]     -    -    -    -    -
[_]     _    _    _    _    _
[%]     %25  %25  %25  %25  %25
[\]     %5C  %5C  %5C  %5C  %5C
----------------------------------------
char  -JAVA-  --JavaScript--  -----PHP------
[ä]   %C3%A4  %C3%A4  %E4     %C3%A4  %C3%A4
[ф]   %D1%84  %D1%84  %u0444  %D1%84  %D1%84

Je recommande de ne pas utiliser l’une de ces méthodes en l’état. Ecrivez votre propre fonction qui fait la bonne chose.

MDN a donné un bon exemple du codage d’URL présenté ci-dessous.

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" + encodeRFC5987ValueChars(fileName);

console.log(header); 
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"


function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            //  so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

https://developer.mozilla.org/ en-US / docs / Web / JavaScript / Référence / Global_Objects / encodeURIComponent

N'oubliez pas non plus qu'ils encodent tous différents jeux de caractères et sélectionnez celui dont vous avez besoin. encodeURI () encode moins de caractères que encodeURIComponent (), ce qui encode moins de caractères (mais aussi différents, du point de dannyp) à l'échappement ().

Aux fins de l'encodage, Javascript a fourni trois fonctions intégrées :

  1. escape() - n'encode pas @*/+Cette méthode est obsolète après l'ECMA 3 et doit donc être évitée.

  2. encodeURI() - n'encode pas ~!@#$&*()=:/,;?+'Il suppose que l'URI est un URI complet et n'encode donc pas les caractères réservés qui ont une signification particulière dans l'URI.Cette méthode est utilisée lorsque l'intention est de convertir l'URL complète au lieu d'un segment spécial d'URL.Exemple - encodeURI('http://stackoverflow.com');va donner - http://stackoverflow.com

  3. encodeURIComponent() -n'encode pas - _ . ! ~ * ' ( )Cette fonction code un composant URI (Uniform Resource Identifier) ​​en remplaçant chaque instance de certains caractères par une, deux, trois ou quatre séquences d'échappement représentant le codage UTF-8 du caractère.Cette méthode doit être utilisée pour convertir un composant d'URL.Par exemple, certaines entrées utilisateur doivent être annexées - encodeURI('http://stackoverflow.com');donnera - http%3A%2F%2Fstackoverflow.com

Tout cet encodage est effectué en UTF 8 c'est à dire que les caractères seront convertis au format UTF-8.

encodeURIComponent diffère de encodeURI en ce sens qu'il code les caractères réservés et le signe numérique # de encodeURI

J'ai constaté qu'expérimenter différentes méthodes constituait un bon contrôle de la santé mentale même après avoir bien maîtrisé leurs utilisations et leurs capacités.

À cette fin, j’ai trouvé ce site extrêmement utile à confirmer mes soupçons que je fais quelque chose de manière appropriée. Il s’est également avéré utile pour décoder une chaîne encodée par l’URG qui peut être assez difficile à interpréter. Un excellent marque-page à avoir:

http://www.the-art-of-web.com / javascript / escape /

Inspiré par de Johann's tableau , j’ai décidé d’allonger le tableau. Je voulais voir quels caractères ASCII étaient encodés.

 capture d'écran de console.table

var ascii = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

var encoded = [];

ascii.split("").forEach(function (char) {
    var obj = { char };
    if (char != encodeURI(char))
        obj.encodeURI = encodeURI(char);
    if (char != encodeURIComponent(char))
        obj.encodeURIComponent = encodeURIComponent(char);
    if (obj.encodeURI || obj.encodeURIComponent)
        encoded.push(obj);
});

console.table(encoded);

Le tableau montre uniquement les caractères encodés. Les cellules vides signifient que l'original et les caractères encodés sont les mêmes.

Juste pour être extra, j'ajoute une autre table pour urlencode() vs rawurlencode() . La seule différence semble être le codage du caractère d'espace.

 capture d'écran de console.table

<script>
<?php
$ascii = str_split(" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~", 1);
$encoded = [];
foreach ($ascii as $char) {
    $obj = ["char" => $char];
    if ($char != urlencode($char))
        $obj["urlencode"] = urlencode($char);
    if ($char != rawurlencode($char))
        $obj["rawurlencode"] = rawurlencode($char);
    if (isset($obj["rawurlencode"]) || isset($obj["rawurlencode"]))
        $encoded[] = $obj;
}
echo "var encoded = " . json_encode($encoded) . ";";
?>
console.table(encoded);
</script>

J'ai cette fonction ...

var escapeURIparam = function(url) {
    if (encodeURIComponent) url = encodeURIComponent(url);
    else if (encodeURI) url = encodeURI(url);
    else url = escape(url);
    url = url.replace(/\+/g, '%2B'); // Force the replacement of "+"
    return url;
};

La réponse acceptée est bonne. Pour prolonger la dernière partie:

  

Notez qu'encodeURIComponent n'échappe pas au caractère '. Un commun   le bogue est de l’utiliser pour créer des attributs HTML tels que href = 'MyUrl', qui   pourrait souffrir d'un bug d'injection. Si vous construisez du HTML à partir de   chaînes, utilisez soit " au lieu de 'pour les citations d'attributs, ou ajoutez un   couche supplémentaire de codage ('peut être codée sous la forme% 27).

Si vous voulez être prudent, encoder en pourcentage les caractères non conservés devrait également être encodé.

Vous pouvez utiliser cette méthode pour les échapper (source Mozilla )

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

// fixedEncodeURIComponent("'") --> "%27"

Réécriture moderne de la réponse de @ johann-echavarria:

console.log(
    Array(256)
        .fill()
        .map((ignore, i) => String.fromCharCode(i))
        .filter(
            (char) =>
                encodeURI(char) !== encodeURIComponent(char)
                    ? {
                          character: char,
                          encodeURI: encodeURI(char),
                          encodeURIComponent: encodeURIComponent(char)
                      }
                    : false
        )
)

Ou si vous pouvez utiliser une table, remplacez console.log par console.table (pour une sortie plus jolie).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top