브라우저 / HTML src =“data : image / jpeg; base64…”에서 이미지 강제 다운로드


85

클라이언트 측에서 이미지를 생성하고 다음과 같이 HTML로 표시합니다.

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgM...."/>

생성 된 이미지를 다운로드 할 수있는 가능성을 제공하고 싶습니다.

브라우저가 파일 저장 대화 상자를 열고 있다는 것을 어떻게 알 수 있습니까 (또는 다운로드 폴더에 크롬이나 파이어 폭스와 같은 이미지를 다운로드 할 것입니다). 사용자가 마우스 오른쪽 버튼을 클릭하지 않고 이미지를 저장하고 이미지로 저장할 수 있습니다 .

서버 상호 작용이없는 솔루션을 선호합니다. 그래서 먼저 이미지를 업로드 한 다음 다운로드를 시작하면 가능하다는 것을 알고 있습니다.

감사합니다!

답변:


119

간단하게 교체 image/jpeg와 함께 application/octet-stream. 클라이언트는 URL을 인라인 가능 리소스로 인식하지 못하고 다운로드 대화 상자를 표시합니다.

간단한 JavaScript 솔루션은 다음과 같습니다.

//var img = reference to image
var url = img.src.replace(/^data:image\/[^;]+/, 'data:application/octet-stream');
window.open(url);
// Or perhaps: location.href = url;
// Or even setting the location of an <iframe> element, 

또 다른 방법은 blob:URI 를 사용하는 것입니다 .

var img = document.images[0];
img.onclick = function() {
    // atob to base64_decode the data-URI
    var image_data = atob(img.src.split(',')[1]);
    // Use typed arrays to convert the binary data to a Blob
    var arraybuffer = new ArrayBuffer(image_data.length);
    var view = new Uint8Array(arraybuffer);
    for (var i=0; i<image_data.length; i++) {
        view[i] = image_data.charCodeAt(i) & 0xff;
    }
    try {
        // This is the recommended method:
        var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
    } catch (e) {
        // The BlobBuilder API has been deprecated in favour of Blob, but older
        // browsers don't know about the Blob constructor
        // IE10 also supports BlobBuilder, but since the `Blob` constructor
        //  also works, there's no need to add `MSBlobBuilder`.
        var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
        bb.append(arraybuffer);
        var blob = bb.getBlob('application/octet-stream'); // <-- Here's the Blob
    }

    // Use the URL object to create a temporary URL
    var url = (window.webkitURL || window.URL).createObjectURL(blob);
    location.href = url; // <-- Download!
};

관련 문서


1
어떤 이유로 Chrome 19.0 베타에서 이음새가 깨지지 만 Chrome 18 및 Firefox에서 작동하므로 괜찮습니다. 파일 이름을 설정할 수 있습니까?
alex

데이터 URI에서 파일 이름을 설정하는 방법은 없습니다. 경우에도 캔버스 / 물방울이 데이터를 내보내는 데 사용되는 파일 이름을 설정할 수 없습니다. 내 대답에 다른 방법을 추가했습니다 (이 방법은 Chrome 19에서 작동한다고 생각합니다).
Rob W

2
첫 번째 방법이 더 이상 크롬 19에서 작동하지 않기 때문에 더 이상 사용되지 않을 것이라고 생각하십니까?
알렉스

1
관련 소스를 찾을 수 없습니다. 또한 Chrome에서 기본 이름을 설정하는 방법을 제안하는 이 답변 을 찾았습니다 (앵커 만 해당, 사용자가 클릭해야 함)
Rob W

또한이 솔루션을 찾았습니다-지금은 크롬 인 것 같습니다. 귀하의 지원에 감사드립니다!
알렉스

96

태그에 다운로드 속성을 사용할 수 있습니다.

<a href="data:image/jpeg;base64,/9j/4AAQSkZ..." download="filename.jpg"></a>

더보기 : https://developer.mozilla.org/en/HTML/element/a#attr-download


1
이미지 소스를 동적으로 생성 할 때이 솔루션을 어떻게 사용할 수 있습니까? 사용자가 클릭하면 몇 가지 계산을 수행하고 base64 이미지를 생성하고 ... 어떻게 강제 다운로드 할 수 있습니까?
Mikhail

크롬에서는이 방법을 사용하여 파일 이름을 설정할 수 없습니다. 다운로드 한 파일의 이름은 무엇이든 "다운로드"로 유지됩니다. 이미지를 ... : 데이터를 사용하는 경우에만 발생
cmaduro

5
나는 이것이 오래된 게시물이라는 것을 알고 있지만 W3Schools 웹 사이트에 따르면 '다운로드'속성은 IE, Safari 및 Opera v에서 지원되지 않습니다. <12 w3schools.com/tags/tryit.asp?filename=tryhtml5_a_download2 사실 IE에서 시도했습니다. 작동하지 않습니다 .... :(
Mirko Lugano

6
이 댓글을 작성할 당시 download속성은 여전히 ​​Safari 및 IE를 지원하지 않습니다.
TheCarver 2015 년

1
base64 길이 제한이 있으므로이 방법을 사용하여 더 큰 이미지를 다운로드 할 수 없습니다.
키란 Chenna

15

나는 생각 의 img 태그가의 자식으로 필요 태그, 다음과 같은 방법 :

<a download="YourFileName.jpeg" href="data:image/jpeg;base64,iVBO...CYII=">
    <img src="data:image/jpeg;base64,iVBO...CYII="></img>
</a>

또는

<a download="YourFileName.jpeg" href="/path/to/OtherFile.jpg">
    <img src="/path/to/OtherFile.jpg"></img>
</a>

# 15에서 설명한대로 a 태그 만 사용하는 것은 Firefox 및 Chrome의 최신 버전 에서 저에게 효과가 없었지만 a.hrefimg.src 태그 에 동일한 이미지 데이터를 넣는 것은 저에게 효과적 이었습니다.

JavaScript에서 다음과 같이 생성 할 수 있습니다.

var data = canvas.toDataURL("image/jpeg");

var img = document.createElement('img');
img.src = data;

var a = document.createElement('a');
a.setAttribute("download", "YourFileName.jpeg");
a.setAttribute("href", data);
a.appendChild(img);

var w = open();
w.document.title = 'Export Image';
w.document.body.innerHTML = 'Left-click on the image to save it.';
w.document.body.appendChild(a);

내부에 img 태그가 필요하다는 것이 아니라 MSDN 문서에 이미 다운로드 된 리소스 만 사용할 수 있다고 명시되어 있습니다. 동일한 데이터를 가진 이미지가있는 한 어디에서나 작동해야합니다. msdn.microsoft.com/en-us/library/cc848897.aspx- "보안상의 이유로 데이터 URI는 다운로드 된 리소스로 제한됩니다. 데이터 URI는 탐색, 스크립팅 또는 프레임 또는 iframe 요소 채우기에 사용할 수 없습니다."
Dimitar Christoff

5

FileSaver.js를 살펴보십시오 . saveAs대부분의 브라우저 별 문제를 처리 하는 편리한 기능을 제공합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.