Forçar o download de uma imagem usando Javascript

Eu quero saber se existe alguma maneira de fazer um script usando JavaScript / jQuery para baixar (abrir uma checkbox de diálogo de download) uma imagem para que o navegador não mostre apenas isso.

Você precisa usar o script do lado do servidor para isso. Pesquisa no stackoverflow .

Como alternativa, seu servidor pode permitir que você altere os headers dinamicamente por meio da configuração.

Solução Apache com mod_headers

Coloque suas imagens para download em um diretório. Dentro deste diretório, crie um arquivo .htaccess com o seguinte conteúdo:

 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 

Pedido de teste:

 HEAD /test/Water%20lilies.jpg HTTP/1.1 Host: localhost 

Resposta de teste:

 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 

Solução HTML5

Você pode usar o atributo de download HTML5 em âncoras :

 

Example 1
Download this image

Example 2

Eu criei uma forma JavaScript pura para forçar o download da imagem, com as seguintes restrições:

  1. Usando HTML5, portanto, não funciona em todos os navegadores IE antes do IE9.
  2. No IE (até 9) limitado a imagens muito pequenas, devido ao limite de tamanho do URL.
  3. O nome da imagem (quando salvo na máquina) não pode ser determinado no código, no Chrome será apenas “download” sem extensão e no Firefox será o que parece ser uma cadeia sem sentido com extensão “.part” – de qualquer forma, o usuário terá que renomear o arquivo para torná-lo utilizável.
  4. Só pode baixar imagens no mesmo domínio – mesma política de origem.

As restrições acima (especialmente a terceira) mais ou menos torna isso inútil, mas ainda assim, a idéia “central” está funcionando e esperamos que em algum momento no futuro seja possível determinar o nome do arquivo, então ele se tornará muito mais útil.

Aqui está o 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 você pode ver, o truque é desenhar a imagem no object canvas , obter os dados binários brutos da imagem e, em seguida, forçar o download usando o tipo mime image/octet-stream e alterar a localização do navegador.

A amostra de uso segue também.

HTML:

   

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); } 

Isso permite “append” o botão de download a todas as imagens existentes, atribuindo o atributo rel do botão ao ID da imagem – o código fará o resto e appendá os events de cliques reais.

Devido à mesma política de origem, não é possível postar um exemplo ao vivo no jsFiddle – eles estão usando o domínio “sandbox” para executar os scripts.

Aqui está uma solução simples que usa o atributo “download” do HTML5:

 document.getElementById('download').click(); 
  

Isso é totalmente possível. Apenas codifique a imagem como Base64, em seguida, faça um window.open com um URL de estilo de data:image/jpg,Base64,...

Eu estou supondo que você quer dizer algo assim:

Ir para o URL no navegador, o URL é: http://example.com/image.png

e, em vez de exibir, o navegador solicita que você salve a imagem?

Tenho certeza de que você não pode forçar isso com o javascript e precisará de uma linguagem do lado do servidor para controlar os headers. E mesmo nesse ponto, você não pode forçar o navegador a baixá-lo, cada usuário reagirá de maneira diferente a qualquer header que você possa enviar.

EDIT: Eu pareço lembrar o header sendo Content-Disposition: attachment;