Pregunta

Al codificar una cadena de consulta para enviarla a un servidor web, ¿cuándo se utiliza? escape() y cuando usas encodeURI() o encodeURIComponent():

Utilice escape:

escape("% +&=");

O

utilizar encodeURI() / encodeURIComponent()

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

encodeURIComponent("var1=value1&var2=value2");
¿Fue útil?

Solución

escapar()

¡No lo uses!escape() se define en la sección B.2.1.2 escapar y el texto de introducción del anexo B dice:

...Todas las características y comportamientos del lenguaje especificados en este anexo tienen una o más características indeseables y, en ausencia de un uso heredado, se eliminarían de esta especificación....
...Los programadores no deben utilizar ni asumir la existencia de estas características y comportamientos al escribir nuevo código ECMAScript....

Comportamiento:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape

Los caracteres especiales están codificados a excepción de:@*_+-./

La forma hexadecimal de los caracteres cuyo valor de unidad de código es 0xFF o menos es una secuencia de escape de dos dígitos: %xx.

Para caracteres con una unidad de código mayor, el formato de cuatro dígitos %uxxxx se utiliza.Esto no está permitido dentro de una cadena de consulta (como se define en RFC3986):

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

Sólo se permite un signo de porcentaje si va seguido directamente de dos dígitos hexadecimales, porcentaje seguido de u No se permite.

codificarURI()

Utilice encodeURI cuando desee una URL que funcione.Haz esta llamada:

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

Llegar:

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

No llame a encodeURIComponent ya que destruiría la URL y devolvería

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

codificarURIComponente()

Utilice encodeURIComponent cuando desee codificar el valor de un parámetro de URL.

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

Luego puedes crear la URL que necesitas:

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

Y obtendrás esta URL completa:

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

Tenga en cuenta que encodeURIComponent no escapa al ' personaje.Un error común es usarlo para crear atributos html como href='MyUrl', que podría sufrir un error de inyección.Si está construyendo html a partir de cadenas, utilice " en lugar de ' para comillas de atributos, o agregue una capa adicional de codificación (' se puede codificar como %27).

Para más información sobre este tipo de codificación puedes consultar: http://en.wikipedia.org/wiki/Percent-encoding

Otros consejos

La diferencia entre encodeURI() y encodeURIComponent() son exactamente 11 caracteres codificados por encodeURIComponent pero no por encodeURI:

Table with the ten differences between encodeURI and encodeURIComponent

Generé esta tabla fácilmente con mesa de consola en Google Chrome con este código:

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

Este artículo me pareció esclarecedor:Locura de Javascript:Análisis de cadenas de consulta

Lo encontré cuando intentaba comprender por qué decodeURIComponent no decodificaba '+' correctamente.Aquí hay un extracto:

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 no codifica -_.!~*'(), causando problemas al publicar datos en php en una cadena xml.

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

fuga general con 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

Puede ver que las comillas simples no están codificadas.Para resolver el problema, creé dos funciones para resolver el problema en mi proyecto, para Codificar URL:

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

Para decodificar URL:

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 función escape() es para escapar de JavaScript, no de HTTP.

Pequeña tabla comparativa Java vs.JavaScript vs.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

Recomiendo no utilizar uno de esos métodos tal como está.Escribe tu propia función que haga lo correcto.

MDN ha dado un buen ejemplo sobre la codificación de URL que se muestra a continuación.

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/Reference/Global_Objects/encodeURIComponent

Recuerde también que todos codifican diferentes conjuntos de caracteres y seleccione el que necesite de forma adecuada.encodeURI() codifica menos caracteres que encodeURIComponent(), que codifica menos caracteres (y también diferentes, según Dannyp) que escape().

Con el fin de codificar, JavaScript ha proporcionado tres funciones incorporadas:

  1. escape() - no codifica @*/+Este método está en desuso después de ECMA 3, por lo que debe evitarse.

  2. encodeURI() - no codifica ~!@#$&*()=:/,;?+'Se supone que el URI es un URI completo, por lo que no codifica caracteres reservados que tengan un significado especial en el URI.Este método se utiliza cuando la intención es convertir la URL completa en lugar de algún segmento especial de URL.Ejemplo - encodeURI('http://stackoverflow.com');daré - http://stackoverflow.com

  3. encodeURIComponent() -no codifica - _ . ! ~ * ' ( )Esta función codifica un componente de Identificador uniforme de recursos (URI) reemplazando cada instancia de ciertos caracteres por una, dos, tres o cuatro secuencias de escape que representan la codificación UTF-8 del carácter.Este método debe usarse para convertir un componente de la URL.Por ejemplo, se debe un ejemplo de entrada del usuario - encodeURI('http://stackoverflow.com');dará - http%3A%2F%2Fstackoverflow.com

Toda esta codificación se realiza en UTF 8, es decir, los caracteres se convertirán al formato UTF-8.

encodeURIComponent se diferencia de encodeURI en que codifica caracteres reservados y el signo numérico # de encodeURI

Descubrí que experimentar con los diversos métodos es una buena prueba de cordura incluso después de tener un buen conocimiento de cuáles son sus diversos usos y capacidades.

Con ese fin he encontrado este sitio web extremadamente útil para confirmar mis sospechas de que estoy haciendo algo correctamente.También ha demostrado ser útil para decodificar una cadena encodeURIComponent que puede ser bastante difícil de interpretar.Un gran marcador para tener:

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

Inspirado por La mesa de Juan, he decidido ampliar la mesa.Quería ver qué caracteres ASCII se codifican.

screenshot of 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);

La tabla muestra solo los caracteres codificados.Las celdas vacías significan que los caracteres originales y codificados son los mismos.


Solo para ser extra, estoy agregando otra tabla para urlencode() vs rawurlencode().La única diferencia parece ser la codificación del carácter espacial.

screenshot of 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>

tengo esta funcion...

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 respuesta aceptada es buena.Para ampliar en la última parte:

Tenga en cuenta que encodeURIComponent no escapa del carácter '.Un error común es usarlo para crear atributos HTML como href = 'myurl', que podría sufrir un error de inyección.Si está construyendo HTML a partir de cadenas, use "en lugar de 'para citas de atributos, o agregue una capa adicional de codificación (' se puede codificar como %27).

Si quieres estar seguro, porcentaje de codificación de caracteres no reservados También debe codificarse.

Puedes usar este método para escapar de ellos (fuente Mozilla)

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

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

Reescritura moderna de la respuesta 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
        )
)

O si puedes usar una mesa, reemplaza console.log con console.table (para una salida más bonita).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top