클릭시 브라우저가 이미지 파일을 다운로드하도록 강제 실행


100

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속성.
— Šime Vidas 2013

6
파일 다운로드를 보장하는 가장 좋은 방법은 서버 측에 콘텐츠 배치를 설정하는 것입니다. 대부분의 클라이언트 측 솔루션은 그다지 안정적이지 않습니다.
— adeneo


: 이미 당신을 위해 대답하는 비슷한 질문이 stackoverflow.com/a/6799284/1948211
— dschu

Karl-Andre Gagnon : 제대로 살펴보세요. [사용하고 싶지 않아 HTML 5에 태그를 지정하지 않았습니다.] 서버를 터치하지 않고
— Amit

답변:


172

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 지원 중단 및 제거 발표


Richard Parnaby-King : HTML 5 속성을 사용하여 수행 할 수 있지만 HTML5 또는 서버 측 도구를 사용하지 않고 수행해야합니다 (가능한 경우) 도우미 감사합니다. :)
— Amit

2
아직 모든 브라우저에서 완전히 지원되지는 않지만 IE 또는 Safari에 관심이없는 경우 좋은 솔루션입니다. caniuse.com/#feat=download
— stacigh 2014 년

HTML5 솔루션에 감사드립니다. 저장하기 전에 파일 이름을 입력 할 수있는 '다른 이름으로 저장'을 허용하는 방법은 무엇입니까?
— teleman

이 파일을 다운로드 할 위치를 제어 할 수 없습니까? 폴더를 직접 다운로드하기 위해 다운로드합니다. html 파일의 로컬 경로를 사용하고 싶습니다.
— Arjun Chiddarwar

1
@ArjunChiddarwar 아니요, 보안 취약점이 열립니다 (누군가가 악성 파일을 Windows 폴더에 직접 저장한다고 상상해보십시오). 다운로드 경로는 브라우저 설정을 기반으로합니다. 예를 들어 기본적으로 Chrome은 다운로드 폴더로 다운로드됩니다.
— Richard Parnaby-King

96

문서에 링크를 추가하여 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가 어디에나있는 웹 앱을위한 아주 좋은 솔루션입니다. 그래도 Chrome에서만 작동합니다 (테스트 설정에서).
— Pavel

호환성 테스트 방법에 대한 아이디어가 있습니까? 이 기술을 사용하고 싶지만 다른 브라우저도 지원해야하므로 지원되지 않는 경우 대안 (예 : 새 창에서 PDF 열기 또는 다운로드 링크)을 제공해야합니다. 누구에게 행운이 있었습니까?
— alexrussell 2014 년

13
훌륭한 솔루션, 감사합니다! 생략 document.body.appendChild(link)하면 firefox에서 작동하지 않습니다. 생성 된 요소를 document.body.removeChild(link);after 로 제거하는 것도 좋습니다.link.click()
— akn

8
최고의 솔루션. DOM 사용에서 쓰레기를 피하기 위해setTimeout( function () { link.parentNode.removeChild( link ); },10 );
— Mephiztopheles

1
질문이 JAVASCRIPT에서 수행하는 방법을 물었으므로 감사가 선택된 답변이어야했습니다.
— codehelp4 2018 년

33

Leeroy & Richard Parnaby-King :

업데이트 : 2018 년 봄부터 이는 교차 출처 href에 대해 더 이상 가능하지 않습니다. 따라서 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

19

2018 년 봄 업데이트

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

이것이 여전히 지원되지만 2018 년 2 월부터 Chrome은 교차 출처 다운로드에 대해이 기능을 비활성화했습니다. 즉, 파일이 동일한 도메인 이름에있는 경우에만 작동합니다.

교차 도메인 다운로드를 비활성화하는 Chrome의 새 업데이트 후 교차 도메인 이미지 다운로드에 대한 해결 방법을 찾았습니다. 필요에 따라이를 함수로 수정할 수 있습니다. 필요한 경우 추가 조사를 통해 이미지 mime 유형 (jpeg, png, gif 등)을 얻을 수 있습니다. 비디오에서도 이와 비슷한 작업을 수행 할 수있는 방법이있을 수 있습니다. 이것이 누군가를 돕기를 바랍니다!

Leeroy & Richard Parnaby-King :

업데이트 : 2018 년 봄부터 이는 교차 출처 href에 대해 더 이상 가능하지 않습니다. 따라서 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로 다시 코딩 한 다음 데이터 URI로 캡슐화 한 다음 로컬에 저장되는 것처럼 보입니다. 그렇다면 이미지 파일의 모든 메타 데이터가 손실됩니다. 또한 JPEG를 다시 인코딩하면 일부 품질이 떨어지고 품질 / 바이트 수 비율이 나빠집니다. 그래도 알아두면 좋습니다. 공유해 주셔서 감사합니다.
— Stéphane Gourichon

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


13
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
사파리 브라우저 다운로드 속성을 지원하지 않습니다
— PRANAV Labhe

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,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz+UMAOsJAP/Z2ccMDA8PD/95eX5NWvsJCOVNQPtfX/8zM8+QePLl38MGBr8JCP+zs9myn/8GBqwpAP/GxgwJCPny78lzYLgjAJ8vAP9fX/+MjMUcAN8zM/9wcM8ZGcATEL+QePdZWf/29uc/P9cmJu9MTDImIN+/r7+/vz8/P8VNQGNugV8AAF9fX8swMNgTAFlDOICAgPNSUnNWSMQ5MBAQEJE3QPIGAM9AQMqGcG9vb6MhJsEdGM8vLx8fH98AANIWAMuQeL8fABkTEPPQ0OM5OSYdGFl5jo+Pj/+pqcsTE78wMFNGQLYmID4dGPvd3UBAQJmTkP+8vH9QUK+vr8ZWSHpzcJMmILdwcLOGcHRQUHxwcK9PT9DQ0O/v70w5MLypoG8wKOuwsP/g4P/Q0IcwKEswKMl8aJ9fX2xjdOtGRs/Pz+Dg4GImIP8gIH0sKEAwKKmTiKZ8aB/f39Wsl+LFt8dgUE9PT5x5aHBwcP+AgP+WltdgYMyZfyywz78AAAAAAAD///8AAP9mZv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAKgALAAAAAA9AEQAAAj/AFEJHEiwoMGDCBMqXMiwocAbBww4nEhxoYkUpzJGrMixogkfGUNqlNixJEIDB0SqHGmyJSojM1bKZOmyop0gM3Oe2liTISKMOoPy7GnwY9CjIYcSRYm0aVKSLmE6nfq05QycVLPuhDrxBlCtYJUqNAq2bNWEBj6ZXRuyxZyDRtqwnXvkhACDV+euTeJm1Ki7A73qNWtFiF+/gA95Gly2CJLDhwEHMOUAAuOpLYDEgBxZ4GRTlC1fDnpkM+fOqD6DDj1aZpITp0dtGCDhr+fVuCu3zlg49ijaokTZTo27uG7Gjn2P+hI8+PDPERoUB318bWbfAJ5sUNFcuGRTYUqV/3ogfXp1rWlMc6awJjiAAd2fm4ogXjz56aypOoIde4OE5u/F9x199dlXnnGiHZWEYbGpsAEA3QXYnHwEFliKAgswgJ8LPeiUXGwedCAKABACCN+EA1pYIIYaFlcDhytd51sGAJbo3onOpajiihlO92KHGaUXGwWjUBChjSPiWJuOO/LYIm4v1tXfE6J4gCSJEZ7YgRYUNrkji9P55sF/ogxw5ZkSqIDaZBV6aSGYq/lGZplndkckZ98xoICbTcIJGQAZcNmdmUc210hs35nCyJ58fgmIKX5RQGOZowxaZwYA+JaoKQwswGijBV4C6SiTUmpphMspJx9unX4KaimjDv9aaXOEBteBqmuuxgEHoLX6Kqx+yXqqBANsgCtit4FWQAEkrNbpq7HSOmtwag5w57GrmlJBASEU18ADjUYb3ADTinIttsgSB1oJFfA63bduimuqKB1keqwUhoCSK374wbujvOSu4QG6UvxBRydcpKsav++Ca6G8A6Pr1x2kVMyHwsVxUALDq/krnrhPSOzXG1lUTIoffqGR7Goi2MAxbv6O2kEG56I7CSlRsEFKFVyovDJoIRTg7sugNRDGqCJzJgcKE0ywc0ELm6KBCCJo8DIPFeCWNGcyqNFE06ToAfV0HBRgxsvLThHn1oddQMrXj5DyAQgjEHSAJMWZwS3HPxT/QMbabI/iBCliMLEJKX2EEkomBAUCxRi42VDADxyTYDVogV+wSChqmKxEKCDAYFDFj4OmwbY7bDGdBhtrnTQYOigeChUmc1K3QTnAUfEgGFgAWt88hKA6aCRIXhxnQ1yg3BCayK44EWdkUQcBByEQChFXfCB776aQsG0BIlQgQgE8qO26X1h8cEUep8ngRBnOy74E9QgRgEAC8SvOfQkh7FDBDmS43PmGoIiKUUEGkMEC/PJHgxw0xH74yx/3XnaYRJgMB8obxQW6kL9QYEJ0FIFgByfIL7/IQAlvQwEpnAC7DtLNJCKUoO/w45c44GwCXiAFB/OXAATQryUxdN4LfFiwgjCNYg+kYMIEFkCKDs6PKAIJouyGWMS1FSKJOMRB/BoIxYJIUXFUxNwoIkEKPAgCBZSQHQ1A2EWDfDEUVLyADj5AChSIQW6gu10bE/JG2VnCZGfo4R4d0sdQoBAHhPjhIB94v/wRoRKQWGRHgrhGSQJxCS+0pCZbEhAAOw==" />


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


3
질문 한 사람과 관련이 있도록 답변에 간단한 설명을 추가하세요.
— AGE

1
link.href = '데이터 : 애플리케이션 / octet-stream을'+에 encodeURIComponent (주소), 따라서 파일을 열 수없는 이러한 부패가 canu 이유 때문에 인 제안
— OM 영원

예,이 답변은 최고의 답변이 될 가치가 있습니다! 저에게 빠진 부분은 잘못된 데이터를 생성하고 파일을 깨뜨리는 "cleanUrl"이었습니다.
— Iulian Pinzaru

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로 다시 코딩 한 다음이를 데이터 URI로 캡슐화 한 다음 로컬에 저장하는 것처럼 보입니다. 그렇다면 이미지 파일의 모든 메타 데이터가 손실됩니다. 또한 JPEG를 다시 인코딩하면 일부 품질이 떨어지고 품질 / 바이트 수 비율이 나빠집니다. 그래도 알아두면 좋습니다. 공유해 주셔서 감사합니다.
— Stéphane Gourichon

2

이 시도:

<a class="button" href="http://www.glamquotes.com/wp-content/uploads/2011/11/smile.jpg" download="smile.jpg">Download image</a>

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=truehref 끝에 포함 하십시오.

이 기술을 사용하여 파일 이름을 동시에 설정할 수도 있습니다.

링크에서 ?download=true&filename=My_Image_File.jpeghref 끝에 포함 하십시오.


2
? download = true는 Google 드라이브에 전달되어 이미지를 다운로드하기 위해 올바른 헤더를 보내도록 서버에 알립니다. 특별히 그렇게 설정하지 않으면 다른 환경에서 작동하는 것이 아닙니다.
— muncherelli

-15

이를 위해 js를 작성할 필요는 없습니다.

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

그리고 브라우저 자체가 자동으로 이미지를 다운로드합니다.

어떤 이유로 작동하지 않으면 다운로드 속성을 추가하십시오. 이 속성을 사용하여 다운로드 가능한 파일의 이름을 설정할 수 있습니다.

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

이미지에 대한 링크는 브라우저가 다르게 구성되어 있지 않는 한 동일한 창에서만 이미지를 엽니 다. 이 download속성은 모든 브라우저에서 지원되지 않습니다.
— 디자인 : Adrian 의해
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.