Trình duyệt / HTML Buộc tải xuống hình ảnh từ src = “data: image / jpeg; base64…”


85

Tôi đang tạo một hình ảnh ở phía máy khách và tôi hiển thị nó bằng HTML như sau:

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

Tôi muốn cung cấp khả năng tải xuống Hình ảnh đã tạo.

Làm thế nào tôi có thể nhận ra rằng trình duyệt đang mở một tệp dialoge lưu tệp (hoặc chỉ tải hình ảnh như chrome hoặc firefox vào thư mục tải xuống sẽ làm được) cho phép người dùng lưu hình ảnh mà không cần nhấp chuột phải và lưu như trên hình ảnh?

Tôi muốn một giải pháp không có sự tương tác của máy chủ. Vì vậy, tôi biết rằng sẽ có thể thực hiện được nếu trước tiên tôi tải Hình ảnh lên và sau đó bắt đầu tải xuống.

Cảm ơn rất nhiều!

Câu trả lời:


119

Đơn giản chỉ cần thay thế image/jpegbằng application/octet-stream. Máy khách sẽ không nhận ra URL là một tài nguyên có thể sử dụng nội tuyến và nhắc một hộp thoại tải xuống.

Một giải pháp JavaScript đơn giản sẽ là:

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

Một phương pháp khác là sử dụng 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!
};

Tài liệu liên quan


1
vì lý do nào đó nó bị hỏng trong Chrome 19.0 beta nhưng nó hoạt động trên Chrome 18 và Firefox nên tôi ổn. Có khả năng đặt tên tệp không?
alex

Không có cách nào để đặt tên tệp trong URI dữ liệu. Ngay cả khi canvas / Blob được sử dụng để xuất dữ liệu, tên tệp không thể được đặt. Tôi đã thêm một phương pháp khác vào câu trả lời của mình (tôi đoán rằng phương pháp này sẽ hoạt động trong Chrome 19).
Rob W

2
Bạn có nghĩ rằng phương pháp đầu tiên sẽ không còn được dùng nữa vì nó không hoạt động trong chrome 19 nữa không?
alex

1
Tôi không thể tìm thấy một nguồn liên quan về nó. Nhân tiện, tôi cũng đã tìm thấy câu trả lời này , gợi ý cách đặt tên mặc định trong Chrome (chỉ ký tự neo, người dùng phải nhấp vào nó)
Rob W

Cũng tìm thấy các giải pháp này - dường như chỉ dành cho chrome cho đến bây giờ. Cảm ơn sự hỗ trợ của bạn!
alex

96

bạn có thể sử dụng thuộc tính tải xuống trên thẻ ...

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

xem thêm: https://developer.mozilla.org/en/HTML/element/a#attr-download


1
Làm cách nào để sử dụng giải pháp này khi tôi tạo nguồn hình ảnh động? Ý tôi là tôi có nút Tải xuống, khi người dùng nhấp vào nó, tôi thực hiện một số tính toán, tạo hình ảnh base64 và ... làm cách nào để buộc tải xuống?
Mikhail

Trong chrome, tôi không thể đặt tên tệp bằng phương pháp này. Tên của tệp đã tải xuống vẫn là "tải xuống" bất kể điều gì. Điều này chỉ xảy ra khi sử dụng dữ liệu: hình ảnh ...
cmaduro

5
Tôi biết đây là một bài đăng cũ nhưng theo thuộc tính 'tải xuống' của trang web W3Schools không được hỗ trợ bởi IE, Safari và Opera v. <12 w3schools.com/tags/tryit.asp?filename=tryhtml5_a_download2 trên thực tế, tôi đã thử nó với IE và nó không hoạt động .... :(
Mirko Lugano

6
Tại thời điểm nhận xét này, downloadthuộc tính vẫn chưa được hỗ trợ Safari và IE.
TheCarver

1
nó có giới hạn độ dài base64, bạn không thể tải xuống hình ảnh lớn hơn bằng cách sử dụng khoảng cách này.
Kiran Chenna

15

Tôi đoán một img thẻ là cần thiết như một đứa trẻ của một một thẻ, theo cách sau:

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

hoặc là

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

Chỉ sử dụng một thẻ như đã giải thích ở # 15 không làm việc cho tôi với phiên bản mới nhất của Firefox và Chrome, nhưng việc đưa dữ liệu hình ảnh như nhau trong cả hai a.hrefimg.src thẻ làm việc cho tôi.

Từ JavaScript, nó có thể được tạo ra như thế này:

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);

không phải là nó cần một thẻ img bên trong, tài liệu MSDN trạng thái rằng chỉ các tài nguyên đã được tải xuống mới có thể được sử dụng - sẽ hoạt động miễn là bạn có hình ảnh với cùng một dữ liệu: base64 ở bất kỳ đâu. msdn .
Dimitar Christoff

5

Hãy xem FileSaver.js . Nó cung cấp một saveAschức năng tiện dụng xử lý hầu hết các vấn đề cụ thể của trình duyệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.