Заставить браузер загружать файлы изображений при нажатии


102

Мне нужен браузер для загрузки файлов изображений так же, как при нажатии на лист Excel.

Есть ли способ сделать это, используя только программирование на стороне клиента?

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript" src="Scripts/jquery-1.10.2.js">
        $(document).ready(function () {
            $("*").click(function () {
                $("p").hide();
            });
        });
        </script>
    </head>

    <script type="text/javascript">
        document.onclick = function (e) {
            e = e || window.event;
            var element = e.target || e.srcElement;
            if (element.innerHTML == "Image") {
                //someFunction(element.href);
                var name = element.nameProp;
                var address = element.href;
                saveImageAs1(element.nameProp, element.href);
                return false; // Prevent default action and stop event propagation
            }
            else
                return true;
        };

        function saveImageAs1(name, adress) {
            if (confirm('you wanna save this image?')) {
                window.win = open(adress);
                //response.redirect("~/testpage.html");
                setTimeout('win.document.execCommand("SaveAs")', 100);
                setTimeout('win.close()', 500);
            }
        }
    </script>

    <body>
        <form id="form1" runat="server">
            <div>
                <p>
                    <a href="http://localhost:55298/SaveImage/demo/Sample2.xlsx" target="_blank">Excel</a><br />
                    <a href="http://localhost:55298/SaveImage/demo/abc.jpg" id="abc">Image</a>
                </p>
            </div>
        </form>
    </body>
</html>

Как это должно работать при загрузке листа Excel (что умеют браузеры)?


7
downloadАтрибут.
Шиме Видас

6
Лучший способ обеспечить загрузку файла - это настроить размещение контента на стороне сервера, большинство решений на стороне клиента не так надежны.
adeneo 08

1
Возможный дубликат: stackoverflow.com/questions/2408146/… ?
Karl-André Gagnon

Есть аналогичный вопрос, на который вам уже дан ответ: stackoverflow.com/a/6799284/1948211
dschu 08

Карл-Андре Ганьон: Пожалуйста, прочтите его как следует. [Я не пометил HTML 5, потому что не хочу его использовать] и без касания сервера
Амит

Ответы:


173

Используя HTML5, вы можете добавить к своим ссылкам атрибут «скачать».

<a href="https://stackoverflow.com/path/to/image.png" download>

Совместимые браузеры предложат загрузить изображение с тем же именем файла (в этом примере image.png).

Если вы укажете значение для этого атрибута, оно станет новым именем файла:

<a href="https://stackoverflow.com/path/to/image.png" download="AwesomeImage.png">

ОБНОВЛЕНИЕ: По состоянию весны 2018 года это уже не возможно для кросса-происхождение hrefс . Поэтому, если вы хотите создать <a href="https://i.imgur.com/IskAzqA.jpg" download>на другом домене, а не imgur.com, он не будет работать должным образом. Объявление о прекращении поддержки и удалении Chrome


Ричард Парнаби-Кинг: Используя атрибут HTML 5, это можно сделать, но мне нужно сделать это БЕЗ использования HTML5 или каких-либо инструментов СЕРВЕРНОЙ СТОРОНЫ (если это возможно). Спасибо за помощников :)
Амит

2
Пока не полностью поддерживается во всех браузерах, но это хорошее решение, если вам не нужны IE или Safari. caniuse.com/#feat=download
stacigh

Спасибо за решение HTML5. Как по-прежнему разрешить сохранение как, чтобы я мог ввести имя файла перед сохранением?
Teleman

Могу ли я контролировать, где этот файл должен быть загружен? Он просто загружается в папку загрузки напрямую. Я хочу, чтобы он использовал локальный путь к файлу html.
Арджун Чиддарвар

1
@ArjunChiddarwar Нет, это открывает уязвимости безопасности (представьте, что кто-то сохраняет вредоносный файл прямо в вашу папку Windows). Путь загрузки зависит от настроек браузера - например, по умолчанию Chrome загружается в вашу папку загрузок.
Ричард Парнаби-Кинг,

99

Мне удалось заставить это работать в Chrome и Firefox, добавив ссылку на документ.

var link = document.createElement('a');
link.href = 'images.jpg';
link.download = 'Download.jpg';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

2
На самом деле это очень хорошее решение для веб-приложений, в которых Javascript есть повсюду. Однако работает только в Google Chrome (в моей тестовой настройке).
Павел

Есть идеи, как проверить совместимость? Я хотел бы использовать эту технику, но должен также поддерживать другие браузеры, поэтому мне нужно предложить альтернативу (например, открыть PDF-файл в новом окне или ссылку для загрузки), когда это не поддерживается. Кому-нибудь повезло с этим?
Alexrussell

13
Отличное решение, спасибо! Обратите внимание, что если вы document.body.appendChild(link)его опустите, он не будет работать в firefox. Также хорошо удалить созданный элемент с помощью document.body.removeChild(link);afterlink.click()
akn

8
лучшее решение. Чтобы избежать мусора при использовании DOMsetTimeout( function () { link.parentNode.removeChild( link ); },10 );
Мефизтофель

1
«Спасибо» должно было быть выбранным ответом, так как был задан вопрос, как это сделать в JAVASCRIPT.
codehelp4

33

Лирой и Ричард Парнаби-Кинг:

ОБНОВЛЕНИЕ: с весны 2018 года это больше невозможно для перекрестных ссылок на источники. Поэтому, если вы хотите создать на другом домене, а не imgur.com, он не будет работать должным образом. Объявление о прекращении поддержки и удалении Chrome

function forceDownload(url, fileName){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
    }
    xhr.send();
}

2
изображение загружается, но не открывается, поскольку указано «Изображение не работает»
picacode

20

Обновление Весна 2018

<a href="/path/to/image.jpg" download="FileName.jpg">

Хотя это все еще поддерживается, по состоянию на февраль 2018 года хром отключил эту функцию для загрузки из разных источников, что означает, что это будет работать, только если файл находится на том же доменном имени.

Я нашел обходной путь для загрузки междоменных изображений после нового обновления Chrome, которое отключило междоменную загрузку. Вы можете преобразовать это в функцию в соответствии со своими потребностями. Возможно, вы сможете получить изображение mime-типа (jpeg, png, gif и т. Д.) С дополнительным исследованием, если вам нужно. Возможно, есть способ сделать что-то подобное и с видео. Надеюсь, это кому-то поможет!

Лирой и Ричард Парнаби-Кинг:

ОБНОВЛЕНИЕ: с весны 2018 года это больше невозможно для перекрестных ссылок на источники. Поэтому, если вы хотите создать на другом домене, а не imgur.com, он не будет работать должным образом. Объявление о прекращении поддержки и удалении Chrome

var image = new Image();
image.crossOrigin = "anonymous";
image.src = "https://is3-ssl.mzstatic.com/image/thumb/Music62/v4/4b/f6/a2/4bf6a267-5a59-be4f-6947-d803849c6a7d/source/200x200bb.jpg";
// get file name - you might need to modify this if your image url doesn't contain a file extension otherwise you can set the file name manually
var fileName = image.src.split(/(\\|\/)/g).pop();
image.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
    canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size
    canvas.getContext('2d').drawImage(this, 0, 0);
    var blob;
    // ... get as Data URI
    if (image.src.indexOf(".jpg") > -1) {
    blob = canvas.toDataURL("image/jpeg");
    } else if (image.src.indexOf(".png") > -1) {
    blob = canvas.toDataURL("image/png");
    } else if (image.src.indexOf(".gif") > -1) {
    blob = canvas.toDataURL("image/gif");
    } else {
    blob = canvas.toDataURL("image/png");
    }
    $("body").html("<b>Click image to download.</b><br><a download='" + fileName + "' href='" + blob + "'><img src='" + blob + "'/></a>");
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Похоже, этот код декодирует изображение в буфер пикселей в памяти браузера, затем перекодирует его как jpeg / png / gif, а затем инкапсулирует это в data-uri, который затем, надеюсь, сохраняется локально. Если это так, это означает, что все метаданные из файла изображения потеряны. Кроме того, перекодирование JPEG приведет к некоторой потере качества и худшему соотношению качество / количество байтов. Тем не менее, это полезно знать. Спасибо, что поделился.
Стефан Гуришон

14
var pom = document.createElement('a');
pom.setAttribute('href', 'data:application/octet-stream,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
pom.style.display = 'none';
document.body.appendChild(pom);
pom.click();
document.body.removeChild(pom);     

5
браузер сафари не поддерживает атрибут загрузки
Пранав Лабхе

14

Более современный подход с использованием Promise и async / await:

toDataURL(url) {
    return fetch(url).then((response) => {
            return response.blob();
        }).then(blob => {
            return URL.createObjectURL(blob);
        });
}

затем

async download() {
        const a = document.createElement("a");
        a.href = await toDataURL("https://cdn1.iconfinder.com/data/icons/ninja-things-1/1772/ninja-simple-512.png");
        a.download = "myImage.png";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
}

Документацию можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch


11

Это общее решение вашей проблемы. Но есть одна очень важная часть: расширение файла должно соответствовать вашей кодировке. И, конечно же, этот параметр содержимого функции downlowadImage должен быть строкой вашего изображения в кодировке base64.

const clearUrl = url => url.replace(/^data:image\/\w+;base64,/, '');

const downloadImage = (name, content, type) => {
  var link = document.createElement('a');
  link.style = 'position: fixed; left -10000px;';
  link.href = `data:application/octet-stream;base64,${encodeURIComponent(content)}`;
  link.download = /\.\w+/.test(name) ? name : `${name}.${type}`;

  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

['png', 'jpg', 'gif'].forEach(type => {
  var download = document.querySelector(`#${type}`);
  download.addEventListener('click', function() {
    var img = document.querySelector('#img');

    downloadImage('myImage', clearUrl(img.src), type);
  });
});
a gif image: <image id="img" src="data:image/gif;base64,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" />


<button id="png">Download PNG</button>
<button id="jpg">Download JPG</button>
<button id="gif">Download GIF</button>


3
Пожалуйста, добавьте к своему ответу краткое объяснение, чтобы сделать его актуальным для человека, который его задал
ВОЗРАСТ

1
link.href = 'data: application / octet-stream,' + encodeURIComponent (address), это повреждает файл и, следовательно, не может быть открыт, могу предположить, почему это так
OM The Eternity

Да, этот ответ заслуживает звания лучшего! Для меня недостающей частью была вещь "cleanUrl", которая генерировала искаженные данные и ломала файл.
Юлиан Пинзару

3

В 2020 году я использую Blob для создания локальной копии изображения, которое браузер загрузит в виде файла. Вы можете протестировать это на этом сайте .

введите описание изображения здесь

(function(global) {
  const next = () => document.querySelector('.search-pagination__button-text').click();
  const uuid = () => Math.random().toString(36).substring(7);
  const toBlob = (src) => new Promise((res) => {
    const img = document.createElement('img');
    const c = document.createElement("canvas");
    const ctx = c.getContext("2d");
    img.onload = ({target}) => {
      c.width = target.naturalWidth;
      c.height = target.naturalHeight;
      ctx.drawImage(target, 0, 0);
      c.toBlob((b) => res(b), "image/jpeg", 0.75);
    };
    img.crossOrigin = "";
    img.src = src;
  });
  const save = (blob, name = 'image.png') => {
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.target = '_blank';
    a.download = name;
    a.click();
  };
  global.download = () => document.querySelectorAll('.search-content__gallery-results figure > img[src]').forEach(async ({src}) => save(await toBlob(src), `${uuid()}.png`));
  global.next = () => next();
})(window);

Похоже, этот код декодирует изображение в буфер пикселей (холст) в памяти браузера, затем перекодирует его как jpeg / png / gif, а затем инкапсулирует это в data-uri, который затем, надеюсь, сохраняется локально. Если это так, это означает, что все метаданные из файла изображения потеряны. Кроме того, перекодирование JPEG приведет к некоторой потере качества и худшему соотношению качество / количество байтов. Тем не менее, это полезно знать. Спасибо, что поделился.
Стефан Гуришон


0
<html>
<head>
<script type="text/javascript">
function prepHref(linkElement) {
    var myDiv = document.getElementById('Div_contain_image');
    var myImage = myDiv.children[0];
    linkElement.href = myImage.src;
}
</script>
</head>
<body>
<div id="Div_contain_image"><img src="YourImage.jpg" alt='MyImage'></div>
<a href="#" onclick="prepHref(this)" download>Click here to download image</a>
</body>
</html>

0

Вы можете напрямую загрузить этот файл с помощью тега привязки без особого кода.
Скопируйте фрагмент, вставьте в текстовый редактор и попробуйте ...!

<html>
<head>
</head>
<body>
   <div>
     <img src="https://upload.wikimedia.org/wikipedia/commons/1/1f/SMirC-thumbsup.svg" width="200" height="200">
      <a href="#" download="https://upload.wikimedia.org/wikipedia/commons/1/1f/SMirC-thumbsup.svg"> Download Image </a>
   </div>
</body>
</html>


2
пожалуйста, добавьте более подробную информацию, например, где можно использовать этот код.
Maciej S.

-2

А как насчет использования функции .click () и тега?

(Сжатая версия)

<a id="downloadtag" href="examplefolder/testfile.txt" hidden download></a>

<button onclick="document.getElementById('downloadtag').click()">Download</button>

Теперь вы можете запустить его с помощью js. Он также не открывает, как другие примеры, графические и текстовые файлы!

(версия js-функции)

function download(){
document.getElementById('downloadtag').click();
}
<!-- HTML -->
<button onclick="download()">Download</button>
<a id="downloadtag" href="coolimages/awsome.png" hidden download></a>


-5

я нашел это

<a href="link/to/My_Image_File.jpeg" download>Download Image File</a>

у меня не сработало. Не знаю почему.

Я обнаружил, что вы можете включить ?download=trueпараметр в конце ссылки для принудительной загрузки. Думаю, я заметил, что эту технику использует Google Диск.

В вашей ссылке включите ?download=trueв конце вашего href.

Вы также можете использовать этот метод для одновременной установки имени файла.

В вашей ссылке включите ?download=true&filename=My_Image_File.jpegв конце вашего href.


2
? download = true передается на Google Диск, чтобы указать их серверу, что нужно отправить правильный заголовок для загрузки изображения. Это не то, что могло бы работать в любой другой среде, если бы она не была специально настроена таким образом.
muncherelli

-16

Для этого не нужно писать js, просто используйте:

<a href="path_to/image.jpg" alt="something">Download image</a>

И браузер сам автоматически скачает изображение.

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

<a href="path_to/image.jpg" download="myImage">Download image</a>

Ссылка на изображение откроет изображение только в том же окне, если ваш браузер не настроен иначе. downloadАтрибут поддерживается не во всех браузерах.
Дизайн Адриан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.