JavaScript 만 사용하여 파일에 데이터를 쓸 수 있습니까?


191

JavaScript를 사용하여 기존 파일에 데이터를 쓰고 싶습니다. 콘솔에서 인쇄하고 싶지 않습니다. 실제로에 데이터를 쓰고 싶습니다 abc.txt. 나는 많은 대답을 읽었지만 콘솔에서 인쇄되는 모든 곳을 읽었습니다. 어떤 곳에서는 코드를 주었지만 작동하지 않습니다. 따라서 실제로 파일에 데이터를 쓰는 방법을 알려주십시오.

코드를 참조했지만 작동하지 않습니다 : 오류 제공 :

잡히지 않은 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 만 사용하거나 NOT을 사용하여 데이터를 파일에 실제로 쓸 수 있습니까?


2
이 형제를 확인하십시오 : stackoverflow.com/questions/585234/…
welbornio

답변:


90

이것에 대한 몇 가지 제안-

  1. 클라이언트 시스템에서 파일을 쓰려고 시도하는 경우 브라우저 간 방식으로 파일을 작성할 수 없습니다. IE에는 "신뢰할 수있는"응용 프로그램이 ActiveX 개체를 사용하여 파일을 읽고 쓸 수 있도록하는 방법이 있습니다.
  2. 서버에 저장하려는 경우 텍스트 데이터를 서버로 전달하고 서버 측 언어를 사용하여 파일 쓰기 코드를 실행하십시오.
  3. 클라이언트 쪽에서 상당히 작은 정보를 저장하기 위해 쿠키를 사용할 수 있습니다.
  4. 로컬 스토리지에 HTML5 API 사용

27
HTML5 API는 최대 5MB입니다.
Pacerier

예, 선택하지 않으면 시스템 파일에 쓸 수 없습니다. 읽기 공식 문서 : w3.org/TR/file-upload/#security-discussion
마노 Ghediya

217

다음을 사용하여 브라우저에서 파일을 만들 수 있습니다 BlobURL.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). 파일 이름 설정은 여전히 download속성을 구현하지 않았기 때문에 Safari에서 작동하지 않습니다 .
쓸모없는 코드

1
나는 사파리 5.1에서 그것을 시도했다 :)
첫 번째 피

1
줄 바꿈 문자가 저장된 문서에서 누락되었습니다
Benny

1
@Benny 개행 문자가 있습니다. JS는 개행 문자 \n를 사용하여 UNIX 프로그램처럼 개행 을 나타냅니다. 메모장과 같은 Windows 프로그램 에서 \n문자를 새 줄로 렌더링하지 않는 것으로 보았을 것입니다 . 당신은 줄 바꿈이 제대로에 텍스트를 놓기 전에, 메모장 및 다른 Windows 프로그램에서 렌더링 할 경우 Blob각각의 교체 \n와 함께 \r\n: text = text.replace(/\n/g, '\r\n').
쓸모없는 코드

2
실제로는 작동하지 않습니다. 그런 것이 전부가 이례적인 것은 아닙니다. 나는 해커가 그것을하는 방법을 보았습니다 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

3
사용자가 파일을 모르는 상태에서 파일을 저장하는 방법에 대한 몇 가지 질문 : 이러한 동작은 디자인에서 피할 수있는 것입니다. 판도라의 사용하기 쉬운 보안 위협 상자가 열립니다. 쿠키는 마케팅 목적으로 데이터를 수집하기위한 것입니다.
Ari Okkonen

참고 Windows 10의 firefox v76에서 html 파일을 .html로 다운로드 할 수 없습니다. 다운로드 끝에 .pdf가 추가되었습니다.
CSchwarz

23

위의 답변은 유용하지만 버튼 클릭시 직접 텍스트 파일을 다운로드하는 데 도움이 되는 코드찾았습니다 . 이 코드에서 filename원하는대로 변경할 수도 있습니다 . HTML5의 순수한 자바 스크립트 함수입니다. 나를 위해 작동합니다!

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
우수한. 오페라에서 나를 위해 일합니다. "document.body.removeChild (event.target)"문에서 "destroyClickedElement"미지의 기능을 대체 할 필요를 제외하고
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을 만듭니다. 크롬 & 파이어 폭스에서 테스트
NaiveCoder

2

나는 여기에 좋은 대답을 찾았지만 더 간단한 방법도 찾았습니다.

링크 요소는 onclick 속성을 가질 수 있으므로 Blob 및 다운로드 링크를 작성하는 단추를 하나의 링크로 결합 할 수 있습니다. (반대에 불가능한 것 같습니다. 버튼에 href를 추가해도 작동하지 않습니다.)

bootstrap스타일링을 제외하고 순수한 자바 스크립트 인을 사용하여 링크를 버튼으로 스타일을 지정할 수 있습니다 .

버튼과 다운로드 링크를 결합하면 추악한 getElementById호출이 덜 필요 하므로 코드가 줄어 듭니다 .

이 예제는 단 한 번의 클릭만으로 텍스트 블롭을 작성하고 다운로드 할 수 있습니다.

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