¿Cómo escapar de una cadena JSON para tenerla en una URL?

129

Usando Javascript, quiero generar un enlace a una página. Los parámetros de la página están en una matriz de Javascript que serializo en JSON.

Entonces me gustaría generar una URL como esa:

http://example.com/?data="MY_JSON_ARRAY_HERE"

¿Cómo necesito escapar de mi cadena JSON (matriz serializada) para incluirla como parámetro en una URL?

Si hay una solución usando JQuery, me encantaría.

Nota: Sí, los parámetros de la página deben estar en una matriz porque hay muchos de ellos. Creo que usaré bit.ly para acortar los enlaces después.

Matthieu Napoli
fuente

Respuestas:

210
encodeURIComponent(JSON.stringify(object_to_be_serialised))
Delan Azabani
fuente
10
Sin embargo, parece que codifica más caracteres de los necesarios (cuando pego el enlace en Firefox, algunos caracteres se revierten (es decir {["). ¿Hay alguna forma de codificar solo los caracteres necesarios para poder acortar mis URL?
Matthieu Napoli
19

Puede usar la encodeURIComponentcodificación segura de URL de partes de una cadena de consulta:

var array = JSON.stringify([ 'foo', 'bar' ]);
var url = 'http://example.com/?data=' + encodeURIComponent(array);

o si está enviando esto como una solicitud AJAX:

var array = JSON.stringify([ 'foo', 'bar' ]);
$.ajax({
    url: 'http://example.com/',
    type: 'GET',
    data: { data: array },
    success: function(result) {
        // process the results
    }
});
Darin Dimitrov
fuente
19

Estaba buscando hacer lo mismo. El problema para mí fue que mi URL se estaba haciendo demasiado larga. Encontré una solución hoy usando la biblioteca jsUrl.js de Bruno Jouhier .

No lo he probado muy a fondo todavía. Sin embargo, aquí hay un ejemplo que muestra las longitudes de caracteres de la salida de la cadena después de codificar el mismo objeto grande usando 3 métodos diferentes:

  • 2651 caracteres usando jQuery.param
  • 1691 caracteres usando JSON.stringify + encodeURIComponent
  • 821 caracteres usando JSURL.stringify

claramente JSURL tiene el formato más optimizado para codificar url un objeto js.

el hilo en https://groups.google.com/forum/?fromgroups=#!topic/nodejs/ivdZuGCF86Q muestra puntos de referencia para la codificación y el análisis.

Nota : Después de la prueba, parece que la biblioteca jsurl.js utiliza funciones ECMAScript 5 como Object.keys, Array.map y Array.filter. Por lo tanto, solo funcionará en navegadores modernos (no, es decir, 8 y menores). Sin embargo, hay polyfills para estas funciones que lo harían compatible con más navegadores.

jcj80
fuente
Desde 0.1.4 también es compatible con IE 6-8 si aún los necesita.
Stoffe
8

Utilizando encodeURIComponent():

var url = 'index.php?data='+encodeURIComponent(JSON.stringify({"json":[{"j":"son"}]})),
génesis
fuente
5

Ofreceré una alternativa extraña. A veces es más fácil usar una codificación diferente, especialmente si se trata de una variedad de sistemas que no manejan todos los detalles de la codificación URL de la misma manera. Este no es el enfoque más convencional, pero puede ser útil en ciertas situaciones.

En lugar de codificar con URL los datos, puede codificarlos en base64. El beneficio de esto es que los datos codificados son muy genéricos y consisten solo en caracteres alfabéticos y, a veces, en los finales =. Ejemplo:

Conjunto de cadenas JSON:

["option", "Fred's dog", "Bill & Trudy", "param=3"]

Esos datos, codificados en URL como el dataparámetro:

"data=%5B%27option%27%2C+%22Fred%27s+dog%22%2C+%27Bill+%26+Trudy%27%2C+%27param%3D3%27%5D"

Lo mismo, codificado en base64:

"data=WyJvcHRpb24iLCAiRnJlZCdzIGRvZyIsICJCaWxsICYgVHJ1ZHkiLCAicGFyYW09MyJd"

El enfoque base64 puede ser un poco más corto, pero lo más importante es que es más simple. A menudo tengo problemas para mover datos codificados con URL entre cURL, navegadores web y otros clientes, generalmente debido a comillas, %signos incrustados, etc. Base64 es muy neutral porque no usa caracteres especiales.

Chris Johnson
fuente
finalmente encontré la dirección (% 26) de mi amigo (&) aquí
Pradeep Kumar Prabaharan
El problema con las cadenas base64 es que pueden contener un carácter de barra diagonal (/), lo que invalidaría la URL ...
ingbabic
Eso es verdad pero puede elegir los caracteres a utilizar en base 64: sustituir /con $, _o de cualquier otro carácter que no requiere codificación URL por RFC 3986.
Chris Johnson
0

La respuesta dada por Delan es perfecta. Simplemente agregue a él, en caso de que alguien quiera nombrar los parámetros o pasar múltiples cadenas JSON por separado, ¡el siguiente código podría ayudar!

JQuery

var valuesToPass = new Array(encodeURIComponent(VALUE_1), encodeURIComponent(VALUE_2), encodeURIComponent(VALUE_3), encodeURIComponent(VALUE_4));

data = {elements:JSON.stringify(valuesToPass)}

PHP

json_decode(urldecode($_POST('elements')));

¡Espero que esto ayude!

foxybagga
fuente
No hay necesidad de urldecode () datos que vienen en PHP $ _POST o cualquier otro (GET, REQEST, etc.). Dependiendo de lo que hagas a partir de ahora, es posible que te abras para un problema de seguridad (inyección SQL, etc.)
Tit Petric el