Принудительно скачать изображение с помощью Javascript - PullRequest
17 голосов
/ 23 июля 2011

Я хочу знать, есть ли какой-нибудь способ сделать скрипт, использующий Javascript / jQuery для загрузки (откройте диалог загрузки) изображения, чтобы браузер не просто показывал его.

Ответы [ 5 ]

35 голосов
/ 23 июля 2011

Для этого вам нужно использовать сценарии на стороне сервера. Поиск по стеку .

Кроме того, ваш сервер может позволить вам динамически изменять заголовки с помощью конфигурации.

Решение Apache с mod_headers

Поместите загружаемые изображения в каталог. Внутри этого каталога создайте файл .htaccess со следующим содержимым:

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

Запрос на тестирование:

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

Тестовый ответ:

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

Решение HTML5

Вы можете использовать атрибут HTML5 download на якорях :

<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>
14 голосов
/ 06 февраля 2012

Я придумала чистый способ JavaScript для принудительной загрузки изображения со следующими ограничениями:

  1. Использование HTML5, поэтому вообще не работает в браузерах IE до IE9.
  2. В IE (даже 9) ограничено очень маленькими изображениями из-за ограничения длины URL.
  3. Имя изображения (при сохранении на машине) не может быть определено в коде, в Chrome оно будет просто «загружаться» без расширения, а в Firefox это будет выглядеть как строковая строка с расширением «.part» - в любом случае пользователю придется переименовать файл, чтобы сделать его пригодным для использования.
  4. Можно загружать изображения только в одном домене - такая же политика происхождения.

Вышеуказанные ограничения (особенно третье) более или менее делают эту бесполезную, но все же, «основная» идея работает , и, надеюсь, когда-нибудь в будущем будет возможно определить имя файла это станет намного полезнее.

Вот код:

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

Как видите, хитрость заключается в рисовании изображения в объекте canvas, получении необработанных двоичных данных изображения и принудительной загрузке с использованием image/octet-stream типа MIME и изменении местоположения браузера.

Пример использования также следует.

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

Это позволяет «прикрепить» кнопку загрузки к каждому существующему изображению, назначив атрибут rel кнопки для идентификатора изображения - код сделает все остальное и прикрепит фактические события щелчка.

Из-за той же политики происхождения нельзя публиковать живой пример на jsFiddle - они используют домен «песочницы» для выполнения сценариев.

4 голосов
/ 25 июня 2015

Вот простое решение, использующее атрибут «скачать» в HTML5:

document.getElementById('download').click();
<a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a>
Если он сможет найти изображение, он загрузит изображение кошки.
0 голосов
/ 29 января 2012

Это вполне возможно.Просто закодируйте изображение как Base64, затем выполните window.open с data:image/jpg,Base64,... -стилем url.

0 голосов
/ 23 июля 2011

Полагаю, вы имеете в виду что-то вроде этого:

Перейти к URL в браузере, URL: http://example.com/image.png

и вместо отображения браузер предлагает сохранить изображение?

Я совершенно уверен, что вы не можете форсировать это с помощью javascript, и вам потребуется серверный язык для управления заголовками. И даже в этот момент вы не можете заставить браузер загрузить его, каждый пользовательский агент будет по-разному реагировать на любые отправляемые вами заголовки.

РЕДАКТИРОВАТЬ: Кажется, я помню заголовок Content-Disposition: attachment;

...