force - javascript download image from url
Force Descargar una imagen con Javascript (5)
Esto es totalmente posible. Simplemente codifica la imagen como Base64 y luego haz una window.open
con una URL de data:image/jpg,Base64,...
-style.
Quiero saber si hay alguna forma de hacer un script usando Javascript / jQuery para descargar (abrir un diálogo de descarga) una imagen para que el navegador no solo lo muestre.
Supongo que quieres decir algo como esto:
Vaya a la URL en el navegador, la URL es: http://example.com/image.png
y en lugar de mostrar, el navegador le pide que guarde la imagen?
Estoy bastante seguro de que no puedes forzar esto con javascript y necesitarás un lenguaje del lado del servidor para controlar los encabezados. E incluso en ese momento no se puede obligar al navegador a descargarlo, cada agente de servicio reaccionará de manera diferente a los encabezados que envíe.
EDIT: parece recordar que el encabezado es Content-Disposition: attachment;
He creado una forma de JavaScript pura para forzar la descarga de la imagen, con las siguientes restricciones:
- Usar HTML5 para que no funcione en todos los navegadores IE antes de IE9.
- En IE (incluso 9) limitado a imágenes muy pequeñas, debido al límite de longitud de URL.
- El nombre de la imagen (cuando se guarda en la máquina) no se puede determinar en el código, en Chrome solo se "descargará" sin extensión y en Firefox será lo que parece una cadena jibberish con extensión ".part" - de cualquier manera, el usuario tendrá que cambiar el nombre del archivo para hacerlo utilizable.
- Solo puede descargar imágenes en el mismo dominio: la misma política de origen.
Las restricciones anteriores (especialmente la tercera) lo vuelven más o menos inútil, pero aún así, la idea "central" está funcionando y es de esperar que en algún momento en el futuro sea posible determinar el nombre del archivo, y será mucho más útil.
Aquí está el código:
function DownloadImage(imageURL) {
var oImage = document.getElementById(imageURL);
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
if (typeof canvas.getContext == "undefined" || !canvas.getContext) {
alert("browser does not support this action, sorry");
return false;
}
try {
var context = canvas.getContext("2d");
var width = oImage.width;
var height = oImage.height;
canvas.width = width;
canvas.height = height;
canvas.style.width = width + "px";
canvas.style.height = height + "px";
context.drawImage(oImage, 0, 0, width, height);
var rawImageData = canvas.toDataURL("image/png;base64");
rawImageData = rawImageData.replace("image/png", "image/octet-stream");
document.location.href = rawImageData;
document.body.removeChild(canvas);
}
catch (err) {
document.body.removeChild(canvas);
alert("Sorry, can''t download");
}
return true;
}
Como puede ver, el truco está en dibujar la imagen en un objeto canvas
, obtener los datos binarios en bruto de la imagen y luego forzar la descarga mediante el uso del tipo mime de image/octet-stream
y cambiar la ubicación del navegador.
Muestra de uso también.
HTML:
<image id="myimage" src="Penguins.jpg" />
<button type="btnDownload" rel="myimage">Download</button>
JavaScript:
window.onload = function() {
var arrButtons = document.getElementsByTagName("button");
for (var i = 0; i < arrButtons.length; i++) {
var oButton = arrButtons[i];
var sRelatedImage = oButton.getAttribute("rel");
if (sRelatedImage && sRelatedImage.length > 0) {
oButton.onclick = function() {
HandleRelatedImage(this, sRelatedImage);
}
}
}
};
function HandleRelatedImage(oButton, sRelatedImage) {
var oImage = document.getElementById(sRelatedImage);
if (!oImage) {
alert("related image ''" + sRelatedImage + "'' does not exist");
return false;
}
return DownloadImage(sRelatedImage);
}
Esto permite "adjuntar" el botón de descarga a cada imagen existente asignando el atributo rel
del botón a la identificación de la imagen: el código hará el resto y adjuntará los eventos de clic reales.
Debido a la misma política de origen, no se puede publicar el ejemplo en vivo en jsFiddle; están usando el dominio "sandbox" para ejecutar los scripts.
Aquí hay una solución simple que usa el atributo HTML5 ''descargar'':
document.getElementById(''download'').click();
<a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a>
Necesita usar secuencias de comandos del lado del servidor para esto. Busque en .
Alternativamente, su servidor podría permitirle alterar los encabezados dinámicamente a través de la configuración.
Solución de Apache con mod_headers
Coloque sus imágenes descargables en un directorio. Dentro de este directorio, cree un archivo .htaccess
con los siguientes contenidos:
SetEnvIf Request_URI "([^/]+/.jpg)$" REQUESTED_IMAGE_BASENAME=$1
SetEnvIf Request_URI "([^/]+/.png)$" REQUESTED_IMAGE_BASENAME=$1
Header set Content-Disposition "attachment; filename=/"%{REQUESTED_IMAGE_BASENAME}e/"" env=REQUESTED_IMAGE_BASENAME
Solicitud de prueba:
HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost
Respuesta de prueba:
HTTP/1.1 200 OK
Date: Sat, 23 Jul 2011 09:03:52 GMT
Server: Apache/2.2.17 (Win32)
Last-Modified: Thu, 23 Aug 2001 14:00:00 GMT
ETag: "26000000017df3-14752-38c32e813d800"
Accept-Ranges: bytes
Content-Length: 83794
Content-Disposition: attachment; filename="Water lilies.jpg"
Content-Type: image/jpeg
Solución HTML5
Puede usar el atributo de download
HTML5 en los anclajes :
<p>Example 1<br>
<a href="http://dummyimage.com/600x400/000/fff.png" download>Download this image</a></p>
<p>Example 2<br>
<a href="http://dummyimage.com/600x400/000/fff.png" download="alternate-filename.png"><img
src="http://dummyimage.com/150x100/000/fff.png"></a></p>