Como evitar que window.open te joda los ámpersands
28 Jul
O también “Cómo abrir un Popup con una URL “escapada” en el GET y no morir en el intento”
Escenario de la catástrofe
Imaginad que queréis llamar a un script servidor desde Javascript, y que una de las variables que se le pasa vÃa GET es una URL. Nada del otro mundo:
<a href="http://server.com/script.php?url=' + varUrl + '">
Lo normal y que a más de uno se le habrá ocurrido ya, es escapar la url para no tener problemas. Escapar no es más que convertir los caracteres conflictivos (“:”,”?”,”&”,”/”…) a sus correspondientes representaciones hexadecimales (más sobre escapar en js). Asà que harÃamos:
url=encodeURIComponent("http://bla.com/index.php?pubid=101852&pag=5");
Con lo que la variable url quedarÃa:
http%3A%2F%2Fbla.com%2Findex.php%3Fpubid%3D101852%26pag%3D5
Hasta aquà estamos de acuerdo, no hemos descubierto nada nuevo y el tema funcionarÃa como se espera. Entonces… ¿dónde carajo está la catástrofe?
La catástrofe en sÃ
No os creáis que con lo de arriba ya se acaba el post, ¡aún falta lo bueno!
La catástrofe nos amenaza el cogote cuando intentamos hacer lo que he comentado arriba, pero abriendo el script servidor que se llama en un Popup. Aaah muchacho, ¡entonces ya la has jodido bien!
<a href="javascript:void(
window.open('http://server.com/script.php
?url=http%3A%2F%2Fbla.com%2Findex.php
%3Fpubid%3D101852%26pag%3D5', null,''));">
Nota para tiquismiquis: los saltos de lÃnea del código anterior los he metido yo a mano para que no se me descojone la página. IrÃa todo en una única lÃnea.
AquÃ, el window.open() que se cree muy listo coge y te hace por su cuenta y riesgo un unescape de la url que va a abrir en el popup, convirtiéndo los valores hexadecimales a sus caracteres ascii y jodiéndote el chiringuito de paso. Y digo jodiéndote el chiringuito porque cuando cargues las variables GET en tu script servidor adivina que te vas a encontrar:
url=http://www.ejemplo.com/index.php?pubid=101852
pag=5
en vez de esto, que serÃa lo que deberÃa ser:
url=http://www.ejemplo.com/index.php?pubid=101852&pag=5
¿No os lo acabáis de creer? ¿Queréis seguir pensando que el window.open() es vuestro amigo fiel y no os joderá los ámpersands? Pobres ilusos. Aquà tenéis un ejemplo en vivo y en directo para acabar de hundir vuestras pobres esperanzas. Y que conste que no he podido encontrar que este comportamiento errático y desalmado del window.open() esté documentado en ningún sitio, asà que el tema es aún más gracioso.
Salvando el mundo
Como he leÃdo por ahà ([1] y [2]) y mira que me ha costado encontrar referencias; la solución es tan sencilla como doble-escapar los ámpersands, de %26 (su representación HEX normal) a %2526. Esto el browser lo procesa la primera vez y se queda en %26, que es lo que nos interesa, nuestro ámpersand escapado.
Asà que al final lo que he acabado haciendo en mi código es lo siguiente:
//encodeURL with ampersand support
function encodeURL(url) {
return encodeURIComponent(url).replace(/%26/g, "%2526");
}
