Unduh file url data

127

Saya bermain-main dengan ide untuk membuat utilitas zip / unzip berbasis JavaScript yang dapat diakses siapa pun dari browser. Mereka cukup menyeret zip mereka langsung ke browser dan itu akan memungkinkan mereka mengunduh semua file di dalamnya. Mereka juga dapat membuat file zip baru dengan menyeret file satu per satu.

Saya tahu akan lebih baik melakukannya di sisi server, tetapi proyek ini hanya untuk sedikit kesenangan.

Menarik file ke browser seharusnya cukup mudah jika saya memanfaatkan berbagai metode yang tersedia. (Gaya Gmail)

Encoding / decoding semoga baik-baik saja. Saya telah melihat beberapa perpustakaan zip as3 jadi saya yakin saya harus baik-baik saja dengan itu.

Masalah saya adalah mengunduh file di bagian akhir.

window.location = 'data:jpg/image;base64,/9j/4AAQSkZJR....' 

ini berfungsi dengan baik di firefox tetapi tidak di chrome.

Saya dapat menyematkan file sebagai gambar dengan baik di chrome menggunakan <img src="data:jpg/image;ba.." />, tetapi file tidak harus berupa gambar. Mereka bisa dalam format apapun.

Adakah yang bisa memikirkan solusi lain atau semacam solusi?

Mikee
sumber
Sayangnya, dukungan saat ini agak terbatas
Casebash

Jawaban:

42

Ide ide:

  • Coba <a href="data:...." target="_blank">(Belum Teruji)

  • Gunakan downloadify alih-alih URL data (juga akan berfungsi untuk IE)

Pekka
sumber
@jcubic terima kasih telah menunjukkan tautan mati. Lokasi unduhan baru tampaknya github.com/dcneiner/Downloadify
Pekka
Jika Anda tidak dapat menggunakan Flash tetapi menjalankan komponen sisi server Java, Anda dapat menggunakan ini: github.com/suprememoocow/databounce . Ini menggunakan Servlet untuk 'memantulkan' data dari klien. Akan cukup mudah untuk melakukan trik yang sama di teknologi sisi server lain, seperti Python, ASP.NET dll
Andrew Newdigate
Apakah ada cara untuk melakukannya tanpa flash? URL data untuk semua browser kecuali IE dan beberapa jenis ActiveX foo untuk IE? (Dengan cara ini saya berhasil memutar musik tanpa flash: audio HTML5 untuk semua browser kecuali IE dan ActiveX untuk IE.)
panzi
Downloadify mengharapkan flash player di browser. Jika pengguna tidak memiliki flash player, maka file tidak dapat diunduh
Jeevanandan J
186

Jika Anda juga ingin memberikan nama yang disarankan untuk file tersebut (alih-alih 'unduh' default), Anda dapat menggunakan yang berikut ini di Chrome, Firefox, dan beberapa versi IE:

function downloadURI(uri, name) {
  var link = document.createElement("a");
  link.download = name;
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  delete link;
}

Dan contoh berikut menunjukkan kegunaannya:

downloadURI("data:text/html,HelloWorld!", "helloWorld.txt");
owencm
sumber
6
Anda dapat menyederhanakannya dengan link.click()alih - alih -fungsi Anda eventFire... jsfiddle.net/ARTsinn/Ezx5m
yckart
3
Solusi bagus. tapi menjadi apa tautan itu setelahnya?
webshaker
6
Variabel 'link' keluar dari ruang lingkup di akhir fungsi (perhatikan kami tidak pernah menambahkannya ke dom) jadi akan segera dikumpulkan sampahnya.
owencm
8
Ini hanya berfungsi di Chrome. Jika Anda ingin berfungsi di Firefox / IE, lihat jawaban dari @MartinoDino.
TrueWill
1
Saya mencoba dengan download.js , seperti yang disarankan di sini dan tampaknya berhasil. :)
joaorodr84
56

function download(dataurl, filename) {
  var a = document.createElement("a");
  a.href = dataurl;
  a.setAttribute("download", filename);
  a.click();
}

download("data:text/html,HelloWorld!", "helloWorld.txt");

atau:

function download(url, filename) {
fetch(url).then(function(t) {
    return t.blob().then((b)=>{
        var a = document.createElement("a");
        a.href = URL.createObjectURL(b);
        a.setAttribute("download", filename);
        a.click();
    }
    );
});
}

download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");

Zibri
sumber
acara klik pada elemen yang tidak ada: D tidak perlu untuk appendchild.
Zibri
1
Iya. Anda cukup memanggil a.click () setelah Anda membuat elemen 'a', dan kemudian menyetel href a.
pengguna1709076
di masa lalu, memanggil a.click () secara langsung tidak akan berfungsi tetapi berfungsi dengan acara tersebut. Sekarang mereka berdua bekerja.
Zibri
1
Ini berfungsi di sebagian besar browser modern, tetapi saya perhatikan bahwa menambahkan ke dokumen kemudian menghapus diperlukan untuk mendukung beberapa browser lama.
owencm
3
Solusi kedua Anda harus digunakan setiap kali dataUri menjadi terlalu besar (tergantung pada browser, tetapi Chrome tidak menerima Uri beberapa megabyte menurut pengalaman saya). Lihat juga stackoverflow.com/questions/38781968/… .
neural5torm
27

Ingin berbagi pengalaman saya dan membantu seseorang terjebak pada unduhan yang tidak berfungsi di Firefox dan memperbarui jawaban untuk 2014. Cuplikan di bawah ini akan berfungsi di firefox dan chrome dan itu akan menerima nama file:

  // Construct the <a> element
  var link = document.createElement("a");
  link.download = thefilename;
  // Construct the uri
  var uri = 'data:text/csv;charset=utf-8;base64,' + someb64data
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  // Cleanup the DOM
  document.body.removeChild(link);
Martino Dino
sumber
4
Sayangnya, ini tidak berfungsi di Safari. Safari sepertinya tidak mengenali downloadatribut tersebut. Terima kasih, ini sedekat yang bisa saya dapatkan saat ini.
Moritz Petersen
ini menyebabkan jendela dialihkan ke nilai href untuk saya di IE 11. prevetDefault (); tidak menghentikan perilaku di IE
b_dubb
1
Terima kasih, juga jika btoatidak ditentukan (misalnya dalam proyek frontend node eslint) const btxt = new Buffer(text).toString('base64'); const uri = 'data:text/csv;charset=utf-8;base64,' + btxt + ';'
Ivan Borshchov
2
menghapus tautan tidak ada gunanya, itu keluar dari ruang lingkup pada baris berikutnya dan akan dikumpulkan sampah, itu bukan target yang valid untuk dihapus.
macdja38
1
tidak perlu document.body.appendChild ... lihat jawaban saya stackoverflow.com/a/45905238/236062
Zibri
13

Berikut adalah solusi JavaScript murni yang saya uji berfungsi di Firefox dan Chrome tetapi tidak di Internet Explorer:

function downloadDataUrlFromJavascript(filename, dataUrl) {

    // Construct the 'a' element
    var link = document.createElement("a");
    link.download = filename;
    link.target = "_blank";

    // Construct the URI
    link.href = dataUrl;
    document.body.appendChild(link);
    link.click();

    // Cleanup the DOM
    document.body.removeChild(link);
    delete link;
}

Solusi lintas browser ditemukan hingga sekarang:

downloadify -> Membutuhkan Flash

databounce -> Diuji di IE 10 dan 11, dan tidak berhasil untuk saya. Membutuhkan servlet dan beberapa kustomisasi. (Salah mendeteksi navigator. Saya harus mengatur IE dalam mode kompatibilitas untuk menguji, charset default di servlet, objek opsi JavaScript dengan jalur servlet yang benar untuk jalur absolut ...) Untuk browser non-IE, ini membuka file di jendela yang sama.

download.js -> http://danml.com/download.html Pustaka lain yang serupa tetapi belum diuji. Mengklaim sebagai JavaScript murni, tidak memerlukan servlet atau Flash, tetapi tidak berfungsi di IE <= 9.

Yesus MC
sumber
download.js cukup bagus. Baru saja melakukan pemeriksaan cepat di IE11, berhasil. Terima kasih banyak!
Ricky Jiao
12

Ada beberapa solusi tetapi mereka bergantung pada HTML5 dan belum diterapkan sepenuhnya di beberapa browser. Contoh di bawah telah diuji di Chrome dan Firefox (sebagian berfungsi).

  1. Contoh kanvas dengan dukungan simpan ke file. Cukup setel Anda document.location.hrefke URI data.
  2. Contoh unduhan jangkar . Ini digunakan <a href="your-data-uri" download="filename.txt">untuk menentukan nama file.
Viacheslav Dobromyslov
sumber
3
contoh kanvas mengarah ke 404
Karel Bílek
Atribut unduhan berfungsi untuk saya, untuk url data pdf di chrome dan safari seluler.
bbsimonbb
7

Menggabungkan jawaban dari @owencm dan @ Chazt3n, fungsi ini memungkinkan pengunduhan teks dari IE11, Firefox, dan Chrome. (Maaf, saya tidak memiliki akses ke Safari atau Opera, tapi tolong tambahkan komentar jika Anda mencoba dan berhasil.)

initiate_user_download = function(file_name, mime_type, text) {
    // Anything but IE works here
    if (undefined === window.navigator.msSaveOrOpenBlob) {
        var e = document.createElement('a');
        var href = 'data:' + mime_type + ';charset=utf-8,' + encodeURIComponent(text);
        e.setAttribute('href', href);
        e.setAttribute('download', file_name);
        document.body.appendChild(e);
        e.click();
        document.body.removeChild(e);
    }
    // IE-specific code
    else {
        var charCodeArr = new Array(text.length);
        for (var i = 0; i < text.length; ++i) {
            var charCode = text.charCodeAt(i);
            charCodeArr[i] = charCode;
        }
        var blob = new Blob([new Uint8Array(charCodeArr)], {type: mime_type});
        window.navigator.msSaveOrOpenBlob(blob, file_name);
    }
}

// Example:
initiate_user_download('data.csv', 'text/csv', 'Sample,Data,Here\n1,2,3\n');
kevinarpe
sumber
1

Untuk siapa pun yang mengalami masalah di IE:

Silakan pilih jawabannya di sini oleh Yetti: menyimpan kanvas secara lokal di IE

dataURItoBlob = function(dataURI) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: 'image/png'});
}

var blob = dataURItoBlob(uri);
window.navigator.msSaveOrOpenBlob(blob, "my-image.png");
Chazt3n
sumber
0

Masalah Anda pada dasarnya bermuara pada "tidak semua browser mendukung ini".

Anda dapat mencoba solusi dan menyajikan file yang telah dibuka zipnya dari objek Flash, tetapi kemudian Anda akan kehilangan kemurnian hanya-JS (bagaimanapun, saya tidak yakin apakah Anda saat ini dapat "menyeret file ke browser" tanpa solusi Flash - apakah itu mungkin fitur HTML5?)

Piskvor meninggalkan gedung
sumber