JavaScriptのみを使用してファイルにデータを書き込むことはできますか?


190

JavaScriptを使用して既存のファイルにデータを書き込みたい。コンソールに印刷したくない。実際にデータを書き込みたいabc.txt。私は答えられた多くの質問を読みましたが、彼らがコンソールで印刷しているすべての場所です。どこかで彼らはコードを与えましたが、それは機能していません。ですから、実際にデータをファイルに書き込む方法を教えてください。

コードを参照しましたが、機能しません。エラーが発生しました:

Uncaught TypeError:不正なコンストラクタ

クロムと

SecurityError:操作は安全ではありません。

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

それでは、Javascriptのみを使用してファイルにデータを実際に書き込むことができますか?


2
このうちの弟チェックstackoverflow.com/questions/585234/...を
welbornio

回答:


89

これに対するいくつかの提案-

  1. クライアントマシンでファイルを書き込もうとしている場合、ブラウザ間でこれを行うことはできません。IEには、「信頼された」アプリケーションがActiveXオブジェクトを使用してファイルを読み書きできるようにするメソッドがあります。
  2. サーバーに保存しようとしている場合は、テキストデータをサーバーに渡し、サーバー側の言語を使用してファイル記述コードを実行するだけです。
  3. かなり小さいクライアント側の情報を保存するには、Cookieを使用できます。
  4. ローカルストレージにHTML5 APIを使用する。

27
HTML5 APIは最大5 MBです。
パセリエ2015年

はい、選択せずにシステムファイルに書き込むことはできません。公式ドキュメントを読む:w3.org/TR/file-upload/#security-discussion
Manoj Ghediya

216

Blobおよびを使用して、ブラウザでファイルを作成できますURL.createObjectURL。最近のすべてのブラウザがこれをサポートしています。

作成したファイルを直接保存することはできません。これは大きなセキュリティ問題を引き起こす可能性がありますが、ユーザーにダウンロードリンクとして提供することはできます。ダウンロード属性をサポートするブラウザでは、リンクのdownload属性を介してファイル名を提案できます。他のダウンロードと同様に、ファイルをダウンロードするユーザーは、ファイル名について最終的な発言権を持ちます。

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

このテクニックを使用してから任意のテキストを保存する次に示しますtextarea

ユーザーにリンクのクリックを要求する代わりに、すぐにダウンロードを開始したい場合は、マウスイベントを使用して、Lifecube回答のように、リンクのマウスクリックをシミュレートできます。この手法を使用する更新された例を作成しました。

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

1
@FirstBlood機能していない部分はありますか、エラーが発生していますか?ファイルとリンクの作成はSafari 7以降で機能するはずです(接頭辞付きのバージョンのを使用している場合、Safari 6でも機能するはずですURL)。Safariではdownload属性がまだ実装されていないため、ファイル名の設定は機能しません。
役に立たないコード

1
私はSafari 5.1で試してみました:)
First Blood

1
保存されたドキュメントに改行文字がない
Benny

1
@Benny改行文字があります。JSは、改行文字\nを使用して、UNIXプログラムのように改行を表します。文字を新しい行としてレンダリングしない\nメモ帳などのWindowsプログラムで表示している可能性があります。あなたは改行が正しくにテキストを入れる前に、メモ帳や他のいくつかのWindowsプログラムでレンダリングする場合はBlob、それぞれを交換する\n\r\ntext = text.replace(/\n/g, '\r\n')
役に立たないコード

2
@ user3241111実はそうではありません。そのようなものはそれほど珍しいことではありません。ハッカーがそれを行う方法を見てきました;-)過去にmouseover、リンク上にファイルを生成するだけでも済んでしまいましたが、処理の量によっては、うまく機能しない場合があります。
役に立たないコード

41

ブラウザのJavaScriptについて話している場合、セキュリティ上の理由からローカルファイルに直接データを書き込むことはできません。HTML 5の新しいAPIでは、ファイルの読み取りのみを許可できます。

ただし、データを書き込み、ユーザーがファイルとしてローカルにダウンロードできるようにする場合。次のコードは機能します:

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

それを使用するには:

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


すごい、Lifecube。私は本当にその機能が必要でしたが、ファイルがダウンロードされていることをユーザーに知られたくないのですが、なんらかのアクションを実行したときに一部のファイルが自動的にダウンロードされていることをユーザーに知らせてしまう可能性があるため、ユーザーから完全に隠したいのです。ウェブサイトで、マーケティングデータ収集の目的でのみ使用していますが、ユーザーに表示せずにファイルをダウンロードする方法を共有していただけませんか?
Just_another_developer 2016年

1
上記のソリューションは古くなっています。html 5 javascript libを検討する必要があるかもしれません。github.com/eligrey/FileSaver.js
Lifecube

FileSaver.jsを使用した@Lifecubeで、ユーザーの操作なしでテキストをファイルに自動的に保存する方法はありますか?ありがとう!JSの新機能。ご協力ありがとう
Nathan

2
ユーザーに知らせずにファイルを保存することについてのいくつかの質問に対して:このような動作は、設計によって回避されているものにすぎません。これにより、Pandoraの使いやすいセキュリティ脅威の箱が開かれます。クッキーは、マーケティング目的でデータを収集するためのものです。
アリOkkonen

Windows 10上のfirefox v76で.htmlとしてhtmlファイルをダウンロードするためにこれを取得できないことに注意してください。ダウンロードの最後に.pdfが追加されています。
CSchwarz

23

上記の答えは役に立ちますが、ボタンをクリックするとテキストファイルを直接ダウンロードするのに役立つコードを見つけました。このコードではfilename、必要に応じて変更することもできます。HTML5での純粋なJavaScript関数です。私のために働く!

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

2
優れた。Operaで私のために働く。不明な関数「destroyClickedElement」を「document.body.removeChild(event.target)」ステートメントで置き換える必要がある場合を除いて
steveOw

3
を使用するときは注意が必要createObjectURLです。JSのほとんどのものとは異なり、それを使用して作成したオブジェクトは、それらへの参照がなくなったときに自動的にガベージコレクションされません。これらは、ページが閉じたときにのみガベージコレクションされます。あなたが使用していないので、URL.revokeObjectURL()最後の呼び出しで使用されるメモリを解放するために、このコードでは、あなたはメモリリークを持っています。ユーザーがsaveTextFile複数回呼び出した場合、ユーザーが解放していないため、ユーザーはますます多くのメモリを消費し続けます。
役に立たないコード


6

新しいBlobソリューションを使用することが不可能である場合、つまり最新のブラウザーで確実に最良のソリューションである場合でも、この単純なアプローチを使用することは依然として可能であり、ファイルサイズに制限があります。

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>


3

上記のユーザー@ useless-codeによるコード(https://stackoverflow.com/a/21016088/327386)を使用してファイルを生成します。ファイルを自動的にダウンロードする場合textFileは、生成されたをこの関数に渡します。

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

5
これが反対票を投じた理由がわかりません。わたしにはできる。反対票を投じた人は、なぜこれが反対票を投じられたのかについて少なくともコメントを残すべきです!
RPM

5
私は反対投票はしませんでしたが、実際に投票についてコメントすることは直接お勧めしません。ユーザーは投稿のコンテンツにコメントし、投稿のコンテンツに投票する必要がありますが、投票にはコメントしないでください。誰かがコメントせずに投票した場合、投票のキャストに応じて、「この回答は役立つ」または「この回答は役に立たない」という意味になります。

これは機能しません。ファイルをダウンロードしません。非表示のiframeを作成するだけです。私は
Chrome

2

ここで良い答えを見つけましたが、より簡単な方法も見つけました。

リンク要素にonclick属性を含めることができるため、BLOBとダウンロードリンクを作成するためのボタンを1つのリンクに組み合わせることができます。(逆は不可能のようです。ボタンにhrefを追加しても機能しません。)

を使用してbootstrap、リンクをボタンとしてスタイル設定できます。これは、スタイル設定を除いて、純粋なJavaScriptです。

ボタンとダウンロードリンクを組み合わせると、getElementById必要な醜い呼び出しが少なくなるため、コードも削減されます。

この例では、テキストブロブを作成してダウンロードするためにボタンを1回クリックするだけです。

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

0

はい、可能ですここにコードがあります

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.