Я хочу знать, есть ли способ сделать script с помощью Javascript/jQuery для загрузки (открыть диалог загрузки) изображение, чтобы браузер не просто отображал его.
Force Загрузить изображение с помощью Javascript
Ответ 1
Для этого вам нужно использовать серверные скрипты. Поиск в stackoverflow.
Кроме того, ваш сервер может позволить вам динамически изменять заголовки с помощью конфигурации.
Решение 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>
Ответ 2
Я придумал чистый способ JavaScript для принудительного скачивания изображения со следующими ограничениями:
- Использование HTML5 так не работает вообще в браузерах IE до IE9.
- В IE (даже 9), ограниченном очень маленькими изображениями, из-за ограничения длины URL.
- Имя изображения (при сохранении на машине) не может быть определено в коде, в Chrome это будет просто "скачать" без расширения, а в Firefox это будет похоже на строку jibberish с расширением ".part" - в любом случае, пользователю придется переименовать файл, чтобы сделать его пригодным для использования.
- Можно загружать только изображения в том же домене - та же самая политика происхождения.
Вышеуказанные ограничения (особенно третье) более или менее делают это бесполезным, но тем не менее, "основная" идея работает и, надеюсь, в какой-то момент в будущем будет возможно определить имя файла то он станет намного полезнее.
Вот код:
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
, получает необработанные двоичные данные изображения, а затем принудительно загружается с использованием типа mime image/octet-stream
и изменения местоположения браузера.
Далее следует пример использования.
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 - они используют домен "песочница" для выполнения сценариев.
Ответ 3
Здесь простое решение, использующее атрибут загрузки HTML5:
document.getElementById('download').click();
<a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a>
Ответ 4
Я предполагаю, что вы имеете в виду что-то вроде этого:
Перейдите к URL-адресу в браузере, URL-адрес: http://example.com/image.png
и вместо отображения браузер предлагает вам сохранить изображение?
Я уверен, что вы не можете заставить это с помощью javascript и для управления заголовками потребуется серверный язык. И даже в этот момент вы не можете заставить браузер загружать его, каждый пользовательский агент будет реагировать по-разному на любые заголовки, которые вы можете отправить.
EDIT: Кажется, я помню заголовок Content-Disposition: attachment;
Ответ 5
Это вполне возможно. Просто закодируйте изображение как Base64, затем выполните window.open
с data:image/jpg,Base64,...
-типом URL.