是否可以只使用JavaScript将数据写入文件?

我想写数据到现有的文件使用JavaScript。 我不想在主机上打印。 我想实际写入数据abc.txt。 我读了很多回答的问题,但他们都是在主机上打印的。 在某些地方,他们给出了代码,但它不起作用。 所以请任何人可以帮助我如何实际写入数据文件

我引用了代码,但它不工作: 它的给出错误:

Uncaught TypeError:非法构造函数

在chrome和

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或不?

789104 次浏览

对此,我有一些建议

  1. 如果你试图在客户端机器上写一个文件,你不能在任何跨浏览器的方式这样做。IE确实有一些方法可以让“受信任的”应用程序使用ActiveX对象来读写文件。
  2. 如果您试图将其保存在服务器上,那么只需将文本数据传递到服务器,并使用一些服务器端语言执行文件编写代码。
  3. 要在客户端存储相当小的信息,可以使用cookie。
  4. 使用HTML5 API进行本地存储。

如果你谈论的是浏览器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');

你可以使用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);
使用上面用户@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;
}
上面的答案是有用的,但是,我找到了代码帮助你直接下载文本文件点击按钮。 在这段代码中,你也可以随心所欲地改变filename。它是纯javascript功能与HTML5。 对我有用!< / p >
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();
}

在不可能使用新的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>

我在这里找到了很好的答案,但也找到了更简单的方法。

创建blob的按钮和下载链接可以组合在一个链接中,因为link元素可以有一个onclick属性。(反过来似乎是不可能的,在按钮上添加href是行不通的。)

你可以使用bootstrap将链接设置为按钮样式,这仍然是纯javascript,除了样式。

结合按钮和下载链接也减少了代码,因为需要更少的那些丑陋的getElementById调用。

这个例子只需要点击一个按钮来创建text-blob并下载它:

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

试一试

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

如果你想下载二进制数据,请查看在这里

更新

2020.06.14我将Chrome升级到83.0及以上SO snippet停止工作(原因:沙箱安全限制)-但JSFiddle版本工作- 在这里

const data = {name: 'Ronn', age: 27};              //sample json
const a = document.createElement('a');
const blob = new Blob([JSON.stringify(data)]);
a.href = URL.createObjectURL(blob);
a.download = 'sample-profile';                     //filename to download
a.click();

在这里检查Blob文档- Blob中数以提供文件类型的额外参数。默认情况下,它将生成.txt文件

当您需要脚本语言的额外处理功能时,可以使用这里的单页本地文件版本。

  1. 将下面的代码保存到一个文本文件中
  2. 将文件扩展名从'.txt'更改为'.html'
  3. 右击在打开……>记事本
  4. 根据需要编写文字处理程序,然后保存
  5. 双击html文件在默认浏览器中打开
  6. 结果将在黑匣子中预览,点击下载可获得结果文本文件

代码:

<!DOCTYPE HTML>
<HTML>
<HEAD>
</HEAD>
<BODY>
<SCRIPT>
// do text manipulation here
let string1 = 'test\r\n';
let string2 = 'export.';
    

// assemble final string
const finalText = string1 + string2;
    

// convert to blob
const data = new Blob([finalText], {type: 'text/plain'});
    

// create file link
const link = document.createElement('a');
link.innerHTML = 'download';
link.setAttribute('download', 'data.txt');
link.href = window.URL.createObjectURL(data);
document.body.appendChild(link);
    

// preview the output in a paragraph
const htmlBreak = string => {
return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
}
const preview = document.createElement('p');
preview.innerHTML = htmlBreak(finalText);
preview.style.border = "1px solid black";
document.body.appendChild(preview);
</SCRIPT>
</BODY>
</HTML>