¿Debo usar encodeURI o encodeURIComponent para codificar URL?

282

¿Cuál de estos dos métodos debería usarse para codificar URL?

Aditya Shukla
fuente
3
También vea stackoverflow.com/a/3608791/632951
Pacerier el
13
Una diferencia importante es que encodeURIno codificará /así: encodeURIComponent("ac/dc")=> ac%2Fdcy encodeURI("ac/dc")=>ac/dc
Esto podría ser útil: "encodeURIComponent() and encodeURI() encode a URI by replacing URL reserved characters with their UTF-8 encoding....They differ because encodeURI does not encode queryString or hash values...URLs do not allow many special characters, like spaces or slashes. However these special characters are part of life, so URL encoding was invented." Fuente
usuario1063287
Consulte también la sección específica titulada encodeURIComponent differs from encodeURI as followsen: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
user1063287

Respuestas:

324

Depende de lo que realmente quieras hacer.

encodeURI supone que la entrada es un URI completo que podría tener algunos caracteres que necesitan codificación.

encodeURIComponent codificará todo con un significado especial, por lo que lo usará para componentes de URI como

var world = "A string with symbols & characters that have special meaning?";
var uri = 'http://example.com/foo?hello=' + encodeURIComponent(world);
Quentin
fuente
108

Si está codificando una cadena para ponerla en un componente de URL (un parámetro de cadena de consulta), debe llamar encodeURIComponent .

Si está codificando una URL existente, llame encodeURI.

SLaks
fuente
1
Si estoy usando ajax, ¿cómo decodifico la url que se pasa a php?
Aditya Shukla
66
Usted no El servidor web lo hace automáticamente.
Quentin
@Aditya: Depende de lo que estés haciendo.
SLaks
@slaks. Estoy pasando parámetros a través de get, así que quiero recuperarlos en php.
Aditya Shukla
2
Bien. Podría haber hablado un poco apresuradamente cuando dije el servidor web lo haría, pero cualquier biblioteca que use para leer sus datos de formulario se encargará de usted.
Quentin
47

xkr.us tiene una gran discusión, con ejemplos. Para citar su resumen:

El método escape () no codifica el carácter + que se interpreta como un espacio en el lado del servidor, así como generado por formularios con espacios en sus campos. Debido a esta deficiencia y al hecho de que esta función no puede manejar correctamente los caracteres que no son ASCII, debe evitar el uso de escape () siempre que sea posible. La mejor alternativa suele ser encodeURIComponent ().

escape () no codificará: @ * / +

El uso del método encodeURI () es un poco más especializado que escape (), ya que codifica los URI en lugar de la cadena de consulta, que es parte de una URL. Use este método cuando necesite codificar una cadena para usarla en cualquier recurso que use URI y necesite que ciertos caracteres permanezcan sin codificar. Tenga en cuenta que este método no codifica el carácter ', ya que es un carácter válido dentro de los URI.

encodeURI () no codificará: ~! @ # $ & * () =: /,;? + '

Por último, el método encodeURIComponent () debe usarse en la mayoría de los casos al codificar un solo componente de un URI. Este método codificará ciertos caracteres que normalmente se reconocerían como caracteres especiales para los URI para que se puedan incluir muchos componentes. Tenga en cuenta que este método no codifica el carácter ', ya que es un carácter válido dentro de los URI.

encodeURIComponent () no codificará: ~! * () '

BrianFreud
fuente
Recientemente aprendido Los servidores TOMCAT 9 son más particulares sobre lo que puede enviar a la URL. encodeURIComponent () parece funcionar mejor en casos en los que tiene "espacios" en lo que necesita codificar. A Tomcat 8 no le importó, pero 9 es mucho más particular.
Aggie Jon de 87
Así, en otras palabras, encodeURIun error si usted está tratando de convertir un nombre de archivo a una dirección URL y el nombre del archivo tiene #en ella
gman
17

Aquí hay un resumen.

  1. escape () no codificará @ * _ + -. / /

    No lo uses.

  2. encodeURI () no codificará AZ az 0-9; , /? : @ & = + $ - _. ! ~ * '() #

    Úselo cuando su entrada sea una URL completa como ' https://searchexample.com/search?q=wiki '

  3. encodeURIComponent () no codificará AZ az 0-9 - _. ! ~ * '() Úselo cuando su entrada es parte de una URL completa, por ejemplo const queryStr = encodeURIComponent(someString)
Frank Wang
fuente
1
Esta es una excelente respuesta porque dice exactamente lo que hacen. Sin embargo, todavía tengo una pregunta sobre qué debo usar y cuándo. ¿Qué sucede si mi componente URI es una URL completa? ¿Debo usar la Regla 2 o la Regla 3 desde arriba O tal vez AMBOS como encodeURIComponent (encodeURI (theCompleteURI))
Panu Logic
10

encodeURIComponent (): asume que su argumento es una parte (como el protocolo, el nombre de host, la ruta o la cadena de consulta) de un URI. Por lo tanto, escapa a los caracteres de puntuación que se utilizan para separar las porciones de un URI.

encodeURI (): se utiliza para codificar la url existente

Gopal
fuente
7

Diferencia entre encodeURIy encodeURIComponent:

encodeURIComponent(value)se utiliza principalmente para codificar valores de parámetros queryString, y codifica todos los caracteres aplicables en value. encodeURIignora el prefijo de protocolo ( http://) y el nombre de dominio.


En casos muy, muy raros, cuando desea implementar la codificación manual para codificar caracteres adicionales (aunque no es necesario codificarlos en casos típicos) como:, ! *entonces puede usar:

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

( fuente )

T.Todua
fuente
66
No debes escapar de esos personajes en url.
Arashsoft
Como dice la documentación citada: "estos personajes no tienen usos formales de delimitación de URI"
caesarsol
@caesarsol entonces, ¿debería editar mi respuesta? hágame saber sus pensamientos porque no puedo entender lo que significa esa documentación citada ..
T.Todua
es inútil codificar estos caracteres, a menos que esté haciendo algo fuera de los casos normales de uso de codificación de URL :)
caesarsol
2

Otras respuestas describen los propósitos. Estos son los caracteres que cada función convertirá realmente :

control = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
        + '\x10\x11\x12\x13\x14\X15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F'
                                                                    + '\x7F'
encodeURI         (control + ' "%<>[\\]^`{|}'                             )
encodeURIComponent(control + ' "%<>[\\]^`{|}' + '#$&,:;=?' + '+/@'        )
escape            (control + ' "%<>[\\]^`{|}' + '#$&,:;=?' +       "!'()~")

Todos los caracteres anteriores se convierten en códigos de porcentaje hexadecimal. Espacio para %20, porcentaje para %25, etc. Los siguientes caracteres pasan sin cambios.

Estos son los caracteres que las funciones NO convertirán :

pass_thru = '*-._0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

encodeURI         (pass_thru + '#$&,:;=?' + '+/@' + "!'()~")
encodeURIComponent(pass_thru +                      "!'()~")
escape            (pass_thru +              '+/@'          )
Bob Stein
fuente
-4

Como regla general uso encodeURIComponent. No tenga miedo del nombre largo pensando que es más específico en su uso, para mí es el método más utilizado. Además, no se deje engañar por el uso de encodeURI porque lo probó y parece que está codificando correctamente, probablemente no sea lo que pretendía usar y aunque su simple prueba usando "Fred" en un campo de nombre funcionó, encontrará más tarde, cuando use texto más avanzado, como agregar un signo y un hashtag, fallará. Puede ver las otras respuestas por las razones por las cuales esto es así.

Helzgate
fuente