Generar fichero localmente desde JavaScript en el navegador

835 views
Skip to first unread message

Iñaki Baz Castillo

unread,
May 9, 2011, 6:29:51 AM5/9/11
to jsmeetu...@googlegroups.com
Hola, tengo una consulta para la que prácticamente ya sé la respuesta,
pero tal vez se me escape alguna posibilidad:

- El navegador web abre una página que contiene un código JavaScript
(una especie de aplicación de chat por WebSockets).

- De repente, recibimos, vía WebSocket, datos de un fichero TXT, PNG,
PDF, XLS (lo que sea) codificados en Base64.

- El código JavaScript decodifica dichos datos y obtiene un string que
sería el contenido de dicho fichero en raw.

- Ahora lo que hace falta es poder "abrir"/"visualizar" ese fichero
localmente. Para ello, lo bonito sería (supongo) que el cliente
JavaScript generase un fichero en el sistema de archivos local,
guardase en él el string decodificado, y posteriormente invocase una
acción "open URL" pasándole como ruta
"file:///RUTA_AL_FICHERO_GENERADO.EXTENSION", de tal forma que el
navegador web invocaría el sistema de apertura de ficheros del sistema
operativo y se abriría la aplicación correspondiente (el AcrobatReader
si es un PDF, el editor de textos si es un TXT, el visor de imágenes
si es un PNG, etc).

Obviamente esto último no es posible puesto que, ya lo he comprobado,
JavaScript no permite guardar ficheros localmente. Es más, si se
incluye código "WriteFile(...)" el intérprete JS del navegador lo
ignora *totalmente* hasta el punto que no se puede siguiera debuguear
un warning/error con cosas como el FireBug. Está claro que esto es por
seguridad (si cualquier código JS que descarguemos de cualquier web
pudiese crear ficheros localmente sería un agujero de seguridad
terrible).


He visto algún workaround bastante lamentable como invocar ActiveX
desde JS para crear dicho fichero, cosa que obviamente no quiero (ni
es multiplataforma ni nada).

¿Me dejo alguna posibilidad?

En definitiva, imaginemos que cargamos una web y el código JS tiene un
string que contiene los bytes de una imagen PNG. ¿Hay alguna forma de
mostrar esa imagen o de invocar al visor de imágenes del SO para que
lo abra (teniendo en cuenta que NO le podemos pasar una URL local ni
remota, sino los bytes de la imagen en raw)?.

La "solución" que quiero evitar es la de que el servidor web (de
WebSocket en este caso) tenga que interceptar esos bytes del fichero,
generar un fichero en el server y proporcionar un link HTTP para que
el cliente JavaScript lo abra desde el navegador como si fuese un link
a un archivo remoto normal y corriente.

Gracias.

--
Iñaki Baz Castillo
<i...@aliax.net>

hyperandroid

unread,
May 9, 2011, 7:38:40 AM5/9/11
to jsmeetu...@googlegroups.com
Hasta lo que yo se, que sobre esto es mas bien poco, tu te contestas todo.

Con las imágenes existen 2 excepciones:
  + puedes reconstruir una imagen a partir de su representación binaria/json o la que quieras a partir de un objeto canvas. Para esto necesitas la representación raw de la imagen, no la comprimida en png/gif,etc.
  + tambien puedes definir imágenes inline mediante la descripción base64 de un png. tienes que declarar algo asi en el html o la declaración css: <image src="data:image/png;base64,<base_64_del_png>">

si consigues hacer esto con imagenes, consigues hacerlo con otro tipo de documentos, nos cuentas ;)

Un saludo,
-i

Iñaki Baz Castillo

unread,
May 9, 2011, 7:41:22 AM5/9/11
to jsmeetu...@googlegroups.com
El día 9 de mayo de 2011 13:38, hyperandroid <hypera...@gmail.com> escribió:
> Hasta lo que yo se, que sobre esto es mas bien poco, tu te contestas todo.
> Con las imágenes existen 2 excepciones:
>   + puedes reconstruir una imagen a partir de su representación binaria/json
> o la que quieras a partir de un objeto canvas. Para esto necesitas la
> representación raw de la imagen, no la comprimida en png/gif,etc.
>   + tambien puedes definir imágenes inline mediante la descripción base64 de
> un png. tienes que declarar algo asi en el html o la declaración css: <image
> src="data:image/png;base64,<base_64_del_png>">

Interesante, de esto no tenía ni idea :)


> si consigues hacer esto con imagenes, consigues hacerlo con otro tipo de
> documentos, nos cuentas ;)

Bueno, entiendo que una cosa es hacerlo con imágenes (que pueden ser
renderizadas dentro de HTML por lo tanto dentro de la web que ve el
usuario) y otra cosa es cualquier otro tipo de archivos (PDF, XLS, un
EXE, etc...).

David Santamaria

unread,
May 9, 2011, 7:50:26 AM5/9/11
to jsmeetu...@googlegroups.com
Hola Iñaki,
Complementando un poco la respuesta

El 9 de mayo de 2011 13:41, Iñaki Baz Castillo <i...@aliax.net> escribió:
>
> El día 9 de mayo de 2011 13:38, hyperandroid <hypera...@gmail.com> escribió:
> > Hasta lo que yo se, que sobre esto es mas bien poco, tu te contestas todo.
> > Con las imágenes existen 2 excepciones:
> >   + puedes reconstruir una imagen a partir de su representación binaria/json
> > o la que quieras a partir de un objeto canvas. Para esto necesitas la
> > representación raw de la imagen, no la comprimida en png/gif,etc.
> >   + tambien puedes definir imágenes inline mediante la descripción base64 de
> > un png. tienes que declarar algo asi en el html o la declaración css: <image
> > src="data:image/png;base64,<base_64_del_png>">
>
> Interesante, de esto no tenía ni idea :)

http://en.wikipedia.org/wiki/Data_URI_scheme

Se supone que podrias abrir otros documentos como un pdf (en el enlace
viene un ejemplo para abrir un HTML)

window.open('data:text/html;charset=utf-8,%3C%21DOCTYPE%20'+
'html%3E%0D%0A%3Chtml%20lang%3D%22en%22%3E%0D%0A%3Chead%'+
'3E%3Ctitle%3EEmbedded%20Window%3C%2Ftitle%3E%3C%2Fhead%'+
'3E%0D%0A%3Cbody%3E%3Ch1%3E42%3C%2Fh1%3E%3C%2Fbody%3E%0A'+
'%3C%2Fhtml%3E%0A%0D%0A','_blank','height=300,width=400');

Todo sera probar :)

>
>
> > si consigues hacer esto con imagenes, consigues hacerlo con otro tipo de
> > documentos, nos cuentas ;)
>
> Bueno, entiendo que una cosa es hacerlo con imágenes (que pueden ser
> renderizadas dentro de HTML por lo tanto dentro de la web que ve el
> usuario) y otra cosa es cualquier otro tipo de archivos (PDF, XLS, un
> EXE, etc...).
>
>
> Gracias.
>
>
> --
> Iñaki Baz Castillo
> <i...@aliax.net>

--
David.

Iñaki Baz Castillo

unread,
May 9, 2011, 7:58:50 AM5/9/11
to jsmeetu...@googlegroups.com
El día 9 de mayo de 2011 13:50, David Santamaria
<d.high...@gmail.com> escribió:
> Hola Iñaki,

Aupa David ;)


> Complementando un poco la respuesta
>
> El 9 de mayo de 2011 13:41, Iñaki Baz Castillo <i...@aliax.net> escribió:
>>
>> El día 9 de mayo de 2011 13:38, hyperandroid <hypera...@gmail.com> escribió:
>> > Hasta lo que yo se, que sobre esto es mas bien poco, tu te contestas todo.
>> > Con las imágenes existen 2 excepciones:
>> >   + puedes reconstruir una imagen a partir de su representación binaria/json
>> > o la que quieras a partir de un objeto canvas. Para esto necesitas la
>> > representación raw de la imagen, no la comprimida en png/gif,etc.
>> >   + tambien puedes definir imágenes inline mediante la descripción base64 de
>> > un png. tienes que declarar algo asi en el html o la declaración css: <image
>> > src="data:image/png;base64,<base_64_del_png>">
>>
>> Interesante, de esto no tenía ni idea :)
>
> http://en.wikipedia.org/wiki/Data_URI_scheme
>
> Se supone que podrias abrir otros documentos como un pdf (en el enlace
> viene un ejemplo para abrir un HTML)
>
> window.open('data:text/html;charset=utf-8,%3C%21DOCTYPE%20'+
>  'html%3E%0D%0A%3Chtml%20lang%3D%22en%22%3E%0D%0A%3Chead%'+
>  '3E%3Ctitle%3EEmbedded%20Window%3C%2Ftitle%3E%3C%2Fhead%'+
>  '3E%0D%0A%3Cbody%3E%3Ch1%3E42%3C%2Fh1%3E%3C%2Fbody%3E%0A'+
>  '%3C%2Fhtml%3E%0A%0D%0A','_blank','height=300,width=400');
>
> Todo sera probar :)

Brutal, hay que probarlo y os cuento :)

Iñaki Baz Castillo

unread,
May 9, 2011, 8:20:51 AM5/9/11
to jsmeetu...@googlegroups.com
El día 9 de mayo de 2011 13:58, Iñaki Baz Castillo <i...@aliax.net> escribió:
>> http://en.wikipedia.org/wiki/Data_URI_scheme
>>
>> Se supone que podrias abrir otros documentos como un pdf (en el enlace
>> viene un ejemplo para abrir un HTML)
>>
>> window.open('data:text/html;charset=utf-8,%3C%21DOCTYPE%20'+
>>  'html%3E%0D%0A%3Chtml%20lang%3D%22en%22%3E%0D%0A%3Chead%'+
>>  '3E%3Ctitle%3EEmbedded%20Window%3C%2Ftitle%3E%3C%2Fhead%'+
>>  '3E%0D%0A%3Cbody%3E%3Ch1%3E42%3C%2Fh1%3E%3C%2Fbody%3E%0A'+
>>  '%3C%2Fhtml%3E%0A%0D%0A','_blank','height=300,width=400');
>>
>> Todo sera probar :)
>
> Brutal, hay que probarlo y os cuento :)


¡Funciona perfecto! Ya he abierto PDF codificados en Base64, etc.

¡Gracias!

hyperandroid

unread,
May 9, 2011, 8:50:57 AM5/9/11
to jsmeetu...@googlegroups.com
Perfecto.
Mirando la wikipedia, veo que lo que yo te he pasado, data:image/png tambien forma parte del mismo metodo.
Gracias David. Y graicas Iñaki por probarlo :D
-i

Iñaki Baz Castillo

unread,
May 9, 2011, 8:58:35 AM5/9/11
to jsmeetu...@googlegroups.com
El día 9 de mayo de 2011 14:50, hyperandroid <hypera...@gmail.com> escribió:
> Mirando la wikipedia, veo que lo que yo te he pasado, data:image/png tambien
> forma parte del mismo metodo.
> Gracias David. Y graicas Iñaki por probarlo :D

Gracias a vosotros, estaba ya asumiendo que era imposible ;)

David Santamaria

unread,
May 9, 2011, 9:55:01 AM5/9/11
to jsmeetu...@googlegroups.com
Nada, un placer haber colaborado, y un placer volver a coincidir
contigo en una lista Iñaki (mucho tiempo y muy diferente el topic :P )

--
David.

Iñaki Baz Castillo

unread,
May 9, 2011, 9:56:49 AM5/9/11
to jsmeetu...@googlegroups.com
El día 9 de mayo de 2011 15:55, David Santamaria
<d.high...@gmail.com> escribió:

> Nada, un placer haber colaborado, y un placer volver a coincidir
> contigo en una lista Iñaki

Igualmente ;)


> (mucho tiempo y muy diferente el topic :P )

No te creas que tan diferente ;)

David Santamaria

unread,
Aug 18, 2011, 3:40:05 AM8/18/11
to jsmeetu...@googlegroups.com
Hola,
Me vais a permitir usar las habilidades necromantes con este hilo :).
Solo queria compartir esto que acabo de encontrar
http://html5-demos.appspot.com/static/a.download.html
Y que creo que es una solucion mucho mas elegante que la que discutiamos antes.
Quizas todavia os pueda ser util.
Un saludo.

--
David.

Iñaki Baz Castillo

unread,
Aug 18, 2011, 5:20:10 AM8/18/11
to jsmeetu...@googlegroups.com
El día 18 de agosto de 2011 09:40, David Santamaria
<d.high...@gmail.com> escribió:

> Hola,
> Me vais a permitir usar las habilidades necromantes con este hilo :).
> Solo queria compartir esto que acabo de encontrar
> http://html5-demos.appspot.com/static/a.download.html
> Y que creo que es una solucion mucho mas elegante que la que discutiamos antes.
> Quizas todavia os pueda ser util.
> Un saludo.

Qué brutal parece!

Gracias.

@soyjavi

unread,
Aug 19, 2011, 3:00:06 AM8/19/11
to JS Meetup Bilbao
esta muy bien la verdad, gracias por el aporte David :)

On 18 ago, 11:20, Iñaki Baz Castillo <i...@aliax.net> wrote:
> El día 18 de agosto de 2011 09:40, David Santamaria
> <d.highway...@gmail.com> escribió:
Reply all
Reply to author
Forward
0 new messages