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


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,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" />


<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.