Apakah mungkin untuk menulis data ke file hanya menggunakan JavaScript?

192

Saya ingin Menulis Data ke file yang ada menggunakan JavaScript. Saya tidak ingin mencetaknya di konsol. Saya ingin menulis data abc.txt. Saya membaca banyak pertanyaan tetapi di mana mereka mencetak pada konsol. di beberapa tempat mereka telah memberikan kode tetapi tidak berfungsi. Jadi tolong ada yang bisa membantu saya. Bagaimana sebenarnya menulis data ke File.

Saya merujuk kode tetapi tidak berfungsi: kesalahan pemberiannya:

UnEught TypeError: konstruktor ilegal

pada chrome dan

SecurityError: Operasi tidak aman.

di Mozilla

var f = "sometextfile.txt";

writeTextFile(f, "Spoon")
writeTextFile(f, "Cheese monkey")
writeTextFile(f, "Onion")

function writeTextFile(afilename, output)
{
  var txtFile =new File(afilename);
  txtFile.writeln(output);
  txtFile.close();
}

Jadi bisakah kita benar-benar menulis data ke file hanya menggunakan Javascript atau TIDAK?

Pareshm
sumber

Jawaban:

90

Beberapa saran untuk ini -

  1. Jika Anda mencoba menulis file di mesin klien, Anda tidak bisa melakukan ini dengan cara lintas-browser. IE memang memiliki metode untuk mengaktifkan aplikasi "tepercaya" untuk menggunakan objek ActiveX untuk membaca / menulis file.
  2. Jika Anda mencoba untuk menyimpannya di server Anda maka cukup kirimkan data teks ke server Anda dan jalankan kode penulisan file menggunakan beberapa bahasa sisi server.
  3. Untuk menyimpan beberapa informasi di sisi klien yang sangat kecil, Anda dapat menggunakan cookie.
  4. Menggunakan API HTML5 untuk Penyimpanan Lokal.
Sujit Agarwal
sumber
27
API HTML5 maksimal hanya 5 mb.
Pacerier
Ya, Anda tidak dapat menulis ke file sistem tanpa memilihnya. Baca Documents Resmi: w3.org/TR/file-upload/#security-discussion
Manoj Ghediya
217

Anda dapat membuat file di browser menggunakan Blobdan URL.createObjectURL. Semua browser terbaru mendukung ini .

Anda tidak dapat langsung menyimpan file yang Anda buat, karena itu akan menyebabkan masalah keamanan besar-besaran, tetapi Anda dapat menyediakannya sebagai tautan unduhan untuk pengguna. Anda dapat menyarankan nama file melalui downloadatribut tautan, di browser yang mendukung atribut unduhan. Seperti halnya unduhan lainnya, pengguna yang mengunduh file tersebut akan memiliki hak suara terakhir atas nama file tersebut.

var textFile = null,
  makeTextFile = function (text) {
    var data = new Blob([text], {type: 'text/plain'});

    // If we are replacing a previously generated file we need to
    // manually revoke the object URL to avoid memory leaks.
    if (textFile !== null) {
      window.URL.revokeObjectURL(textFile);
    }

    textFile = window.URL.createObjectURL(data);

    // returns a URL you can use as a href
    return textFile;
  };

Berikut adalah contoh yang menggunakan teknik ini untuk menyimpan teks sewenang-wenang dari atextarea .

Jika Anda ingin segera memulai download bukan membutuhkan pengguna untuk mengklik pada link, Anda dapat menggunakan peristiwa mouse untuk mensimulasikan klik mouse pada link sebagai Lifecube 's jawaban lakukan. Saya telah membuat contoh yang diperbarui yang menggunakan teknik ini.

  var create = document.getElementById('create'),
    textbox = document.getElementById('textbox');

  create.addEventListener('click', function () {
    var link = document.createElement('a');
    link.setAttribute('download', 'info.txt');
    link.href = makeTextFile(textbox.value);
    document.body.appendChild(link);

    // wait for the link to be added to the document
    window.requestAnimationFrame(function () {
      var event = new MouseEvent('click');
      link.dispatchEvent(event);
      document.body.removeChild(link);
    });

  }, false);
Kode tidak berguna
sumber
1
@FirstBlood Bagian mana yang tidak berfungsi, apakah Anda mendapatkan kesalahan? Pembuatan file dan tautan harus berfungsi di Safari 7+ (saya percaya bahwa hal-hal juga harus berfungsi di Safari 6 jika Anda menggunakan versi awalan dari URL). Pengaturan nama file tidak akan berfungsi di Safari karena masih belum menerapkan downloadatribut .
Kode Tidak Berguna
1
Saya sudah mencobanya di Safari 5.1 :)
First Blood
1
karakter baris baru hilang dari dokumen yang disimpan
Benny
1
@ Benny, karakter baris baru ada di sana. JS menggunakan karakter baris baru \nuntuk mewakili baris baru seperti yang dilakukan program UNIX. Anda mungkin melihatnya di program Windows, seperti Notepad, yang tidak membuat \nkarakter sebagai baris baru . Jika Anda ingin baris baru akan benar diberikan di Notepad dan beberapa program Windows lainnya, sebelum meletakkan teks ke dalam Blobmengganti setiap \ndengan \r\n: text = text.replace(/\n/g, '\r\n').
Kode Tidak Berguna
2
@ user3241111 Tidak juga, ini seharusnya bekerja. Hal-hal seperti itu tidak biasa. Saya telah melihat cara-cara peretas untuk melakukannya ;-) Di masa lalu saya juga lolos dengan hanya membuat file di mouseovertautan, tetapi tergantung pada seberapa banyak pemrosesan yang dilakukan yang mungkin tidak bekerja dengan baik.
Kode Tidak Berguna
41

Jika Anda berbicara tentang javascript browser, Anda tidak dapat menulis data langsung ke file lokal karena alasan keamanan. API HTML 5 baru hanya dapat memungkinkan Anda membaca file.

Tetapi jika Anda ingin menulis data, dan memungkinkan pengguna untuk mengunduh sebagai file ke lokal. kode berikut berfungsi:

    function download(strData, strFileName, strMimeType) {
    var D = document,
        A = arguments,
        a = D.createElement("a"),
        d = A[0],
        n = A[1],
        t = A[2] || "text/plain";

    //build download link:
    a.href = "data:" + strMimeType + "charset=utf-8," + escape(strData);


    if (window.MSBlobBuilder) { // IE10
        var bb = new MSBlobBuilder();
        bb.append(strData);
        return navigator.msSaveBlob(bb, strFileName);
    } /* end if(window.MSBlobBuilder) */



    if ('download' in a) { //FF20, CH19
        a.setAttribute("download", n);
        a.innerHTML = "downloading...";
        D.body.appendChild(a);
        setTimeout(function() {
            var e = D.createEvent("MouseEvents");
            e.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            a.dispatchEvent(e);
            D.body.removeChild(a);
        }, 66);
        return true;
    }; /* end if('download' in a) */



    //do iframe dataURL download: (older W3)
    var f = D.createElement("iframe");
    D.body.appendChild(f);
    f.src = "data:" + (A[2] ? A[2] : "application/octet-stream") + (window.btoa ? ";base64" : "") + "," + (window.btoa ? window.btoa : escape)(strData);
    setTimeout(function() {
        D.body.removeChild(f);
    }, 333);
    return true;
}

untuk menggunakannya:

download('the content of the file', 'filename.txt', 'text/plain');

Lifecube
sumber
Luar biasa, Lifecube. Saya benar-benar membutuhkan fungsionalitas itu, walaupun saya tidak ingin pengguna tahu bahwa ada file yang sedang diunduh, saya ingin itu benar-benar disembunyikan dari pengguna karena dapat membuat pengguna takut melihat bahwa beberapa file sedang diunduh secara otomatis setelah melakukan beberapa tindakan di situs web, meskipun kami menggunakannya hanya untuk tujuan pengumpulan data pemasaran, bisakah Anda berbagi cara mengunduh file tanpa membuatnya terlihat oleh pengguna?
Just_another_developer
1
solusi di atas agak ketinggalan jaman. Anda mungkin perlu mempertimbangkan lib javascript html 5. github.com/eligrey/FileSaver.js
Lifecube
@Lifecube menggunakan FileSaver.js, apakah ada cara untuk secara otomatis menyimpan teks ke file tanpa interaksi pengguna? Terima kasih! Baru mengenal JS; semua bantuan Anda dihargai
Nathan
3
Untuk beberapa pertanyaan tentang menyimpan file tanpa diketahui pengguna: Perilaku seperti itu hanya apa yang dihindari oleh desain. Itu akan membuka kotak Pandora dari ancaman keamanan yang mudah digunakan. Cookie adalah untuk mengumpulkan data untuk tujuan pemasaran.
Ari Okkonen
Catatan Saya tidak bisa mendapatkan ini untuk mengunduh file html sebagai .html di firefox v76 pada Windows 10. Unduhan .pdf ditambahkan pada bagian akhir.
CSchwarz
23

Jawaban di atas bermanfaat tetapi, saya menemukan kode yang membantu Anda mengunduh file teks langsung pada klik tombol. Dalam kode ini Anda juga dapat mengubah filenamesesuai keinginan. Ini fungsi javascript murni dengan HTML5. Bekerja untukku!

function saveTextAsFile()
{
    var textToWrite = document.getElementById("inputTextToSave").value;
    var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
    var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value;
      var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL != null)
    {
        // Chrome allows the link to be clicked
        // without actually adding it to the DOM.
        downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    }
    else
    {
        // Firefox requires the link to be added to the DOM
        // before it can be clicked.
        downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
        downloadLink.onclick = destroyClickedElement;
        downloadLink.style.display = "none";
        document.body.appendChild(downloadLink);
    }

    downloadLink.click();
}
Niraj
sumber
2
Luar biasa. Bekerja untuk saya di Opera. Kecuali perlu mengganti fungsi yang tidak diketahui: "destroyClickedElement" dengan pernyataan "document.body.removeChild (event.target)"
steveOw
3
Anda harus berhati-hati saat menggunakan createObjectURL. Tidak seperti kebanyakan hal di JS, objek yang Anda buat dengannya tidak secara otomatis dikumpulkan ketika tidak ada lagi referensi tentang mereka; mereka hanya sampah yang dikumpulkan ketika halaman ditutup. Karena Anda tidak menggunakan URL.revokeObjectURL()kode ini untuk membebaskan memori yang digunakan oleh panggilan terakhir, Anda mengalami kebocoran memori; jika pengguna menelepon saveTextFilebeberapa kali, mereka akan terus mengkonsumsi lebih banyak dan lebih banyak memori karena Anda tidak pernah merilisnya.
Kode Tidak Berguna
20

Mencoba

let a = document.createElement('a');
a.href = "data:application/octet-stream,"+encodeURIComponent("My DATA");
a.download = 'abc.txt';
a.click();

Kamil Kiełczewski
sumber
6

Dalam hal ini tidak mungkin untuk menggunakan Blobsolusi baru , yang pasti solusi terbaik di browser modern, masih mungkin untuk menggunakan pendekatan yang lebih sederhana ini, yang memiliki batas ukuran file dengan cara:

function download() {
                var fileContents=JSON.stringify(jsonObject, null, 2);
                var fileName= "data.json";

                var pp = document.createElement('a');
                pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
                pp.setAttribute('download', fileName);
                pp.click();
            }
            setTimeout(function() {download()}, 500);

$('#download').on("click", function() {
  function download() {
    var jsonObject = {
      "name": "John",
      "age": 31,
      "city": "New York"
    };
    var fileContents = JSON.stringify(jsonObject, null, 2);
    var fileName = "data.json";

    var pp = document.createElement('a');
    pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
    pp.setAttribute('download', fileName);
    pp.click();
  }
  setTimeout(function() {
    download()
  }, 500);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="download">Download me</button>

loretoparisi
sumber
3

Gunakan kode oleh pengguna @ kode tidak berguna di atas ( https://stackoverflow.com/a/21016088/327386 ) untuk menghasilkan file. Jika Anda ingin mengunduh file secara otomatis, berikan textFileyang baru saja dibuat untuk fungsi ini:

var downloadFile = function downloadURL(url) {
    var hiddenIFrameID = 'hiddenDownloader',
    iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
        iframe = document.createElement('iframe');
        iframe.id = hiddenIFrameID;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    }
    iframe.src = url;
}
RPM
sumber
5
Tidak tahu mengapa ini mendapat suara turun. Ini bekerja untuk saya. Orang yang memilih setidaknya harus memberikan komentar mengapa ini tidak dipilih!
RPM
5
Saya tidak mengundurkan diri, tetapi sebenarnya mengomentari pemungutan suara secara langsung tidak disarankan. Pengguna harus mengomentari konten kiriman, dan memberikan suara pada konten kiriman, tetapi mereka tidak boleh mengomentari suara mereka. Jika seseorang memberikan suara tanpa berkomentar, Anda dapat menganggapnya sebagai "jawaban ini berguna" atau "jawaban ini tidak berguna" tergantung pada suara yang diberikan.
Ini tidak berfungsi .. Tidak mengunduh file. Itu hanya menciptakan iframe yang disembunyikan. Saya diuji pada chrome & firefox
NaiveCoder
2

Saya menemukan jawaban yang bagus di sini, tetapi juga menemukan cara yang lebih sederhana.

Tombol untuk membuat gumpalan dan tautan unduhan dapat digabungkan dalam satu tautan, karena elemen tautan dapat memiliki atribut onclick. (Kebalikannya tampaknya tidak mungkin, menambahkan href ke tombol tidak berfungsi.)

Anda dapat menata tautan dengan menggunakan tombol bootstrap, yang masih berupa javascript murni, kecuali untuk penataan.

Menggabungkan tombol dan tautan unduhan juga mengurangi kode, karena lebih sedikit dari getElementByIdpanggilan buruk itu diperlukan.

Contoh ini hanya perlu satu klik tombol untuk membuat gumpalan teks dan mengunduhnya:

<a id="a_btn_writetofile" download="info.txt" href="#" class="btn btn-primary" 
   onclick="exportFile('This is some dummy data.\nAnd some more dummy data.\n', 'a_btn_writetofile')"
>
   Write To File
</a>

<script>
    // URL pointing to the Blob with the file contents
    var objUrl = null;
    // create the blob with file content, and attach the URL to the downloadlink; 
    // NB: link must have the download attribute
    // this method can go to your library
    function exportFile(fileContent, downloadLinkId) {
        // revoke the old object URL to avoid memory leaks.
        if (objUrl !== null) {
            window.URL.revokeObjectURL(objUrl);
        }
        // create the object that contains the file data and that can be referred to with a URL
        var data = new Blob([fileContent], { type: 'text/plain' });
        objUrl = window.URL.createObjectURL(data);
        // attach the object to the download link (styled as button)
        var downloadLinkButton = document.getElementById(downloadLinkId);
        downloadLinkButton.href = objUrl;
    };
</script>
Roland
sumber
0

Ya itu mungkin di sini kodenya

const fs = require('fs') 
let data = "Learning how to write in a file."
fs.writeFile('Output.txt', data, (err) => { 
      
    // In case of a error throw err. 
    if (err) throw err; 
}) 

SM Turag
sumber