*{box-sizing: border-box; } body {margin: 0;}*{box-sizing:border-box;}body{margin-top:0px;margin-right:0px;margin-bottom:0px; margin-left:0px;}。
JavaScript是周围最流行的编程语言之一,主要是因为它在浏览器内运行时处理网站的前端。随着网络标准的进步,我们越来越多地使用它来完成越来越多的任务,而这些任务在早期要么非常困难,要么不可能只用JavaScript完成。
在本教程中,你将学习如何用JavaScript创建和保存文件。我们将讨论三种不同的技术,你可以用来这样做。
使用数据URL来保存文件
保存文件的最简单方法是使用包含所有相关信息的数据URL。这些数据URLs是特殊的URLs,其前缀为data: 方案。它们是在你的HTML文档中嵌入小文件的理想选择。这些URLs遵循以下语法。
data:[<mediatype>][;base64],<data>
mediatype 标记实际上是一种MIME类型,它指定了文档或文件的性质和格式。它的默认值是text/plain;charset=US-ASCII 。base64 令牌是可选的,只有当你想以文本方式存储二进制数据时才需要。我们在所有这些令牌之后指定我们的实际数据。
我们可以使用download 属性来指定我们要在下载后将所有内容放在其中的文件名称。下面是一个共同使用所有这些属性的例子。
<a download="monty.txt" href="data:text/plain;charset=utf-8,My name is Monty.">Download Text File with Name</a>
当你想让整个事情变得动态时,JavaScript可以非常方便。这里有一个例子。
const link = document.querySelector('a.dynamic');
let name = 'Monty';
let text = `My name in ${name}.
I love writing tutorials.`;
link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
link.setAttribute('download', `${name.toLowerCase()}.txt`);
我们首先使用querySelector() 方法选择我们的链接,然后创建一堆变量来存储文件名和其内容。使用模板字元可以使我们轻松地处理多行字符串。
我们通过连接元数据和使用encodeURIComponent() 函数编码的实际内容来创建我们的数据URL。下面的CodePen演示展示了这种使用JavaScript保存文本文件的方法。
使用Blobs来创建和保存文件
Blobs是JavaScript中类似于文件的对象,它包含原始数据。这种原始数据既可以作为文本也可以作为二进制数据来读取。在本教程中,我们将使用Blobs来创建和保存JavaScript中的文件。
我们可以使用Blob() 构造函数来创建我们自己的blob,该构造函数接受一个要放在blob中的特定对象阵列。你可以将数据的MIME类型作为键值对传递给一个对象,该对象是Blob() 构造函数的第二个参数。默认情况下,它是一个空字符串。
我们可以修改上一节中的最后一个例子,用下面的JavaScript代码来使用blob。
const link = document.querySelector('a.simple');
let name = 'Monty';
let text = `My name in ${name}.
I love writing tutorials.`;
var textBlob = new Blob([text], {type: 'text/plain'});
link.setAttribute('href', URL.createObjectURL(textBlob));
link.setAttribute('download', `${name.toLowerCase()}.txt`);
我们通过调用Blob() 构造函数来创建我们的textBlob ,并将我们的text 变量作为一个数组元素传递给它。之后,我们简单地设置href 和download 属性的值。本例中的URL是通过调用createObjectURL() 函数创建的,该函数返回一个字符串,其中包含我们传递给它的对象的URL。
让我们再往前走一步,创建一个blob,其中的文本是从网页上的textarea 元素中动态获得的。你可以在textarea ,然后点击保存文件按钮,将其保存为文件。
const saveBtn = document.querySelector('button.save-file');
let name = 'Monty';
saveBtn.addEventListener('click', function(){
var tempLink = document.createElement("a");
let textArea = document.querySelector("textarea");
var taBlob = new Blob([textArea.value], {type: 'text/plain'});
tempLink.setAttribute('href', URL.createObjectURL(taBlob));
tempLink.setAttribute('download', `${name.toLowerCase()}.txt`);
tempLink.click();
URL.revokeObjectURL(tempLink.href);
});
我们首先获得一个对我们的按钮的引用,然后监听其点击事件。一旦按钮被点击,我们得到我们的textarea 元素的值,并将其转换为一个blob。之后,我们创建一个引用blob的URL,并将其分配给我们创建的锚标签的href 属性。
你可以在下面的CodePen演示中尝试一下。作为练习,尝试修改代码,使其以用户输入的名称而不是静态的东西来保存文件。
如何使用JavaScript将文件保存在一个特定的文件夹中?
让我们先把这个问题解决掉。简而言之,你不可能在JavaScript中任意选择文件的保存目录。只有用户可以控制文件的保存位置。
之所以不允许网络开发者完全控制浏览器保存文件的位置,是与安全有关的。如果每个网站都能访问你设备上的文件系统,互联网的安全性就会大打折扣。他们可以简单地将恶意代码注入你的系统或查看私人信息。
早些时候,除了默认的下载文件夹外,不可能将文件保存在任何地方,而默认的下载文件夹是由浏览器的设置决定的,而不是由个别网站决定。然而,文件系统访问API允许开发者在获得用户授权后建议文件可以保存在哪里。请记住,目前对该API缺乏更广泛的浏览器支持,而支持它的浏览器也只是部分地支持它。
让我们修改上一节的例子,用文件系统访问API在JavaScript中创建和保存一个文件。
const saveBtn = document.querySelector('button.save-file');
let name = 'Monty';
saveBtn.addEventListener('click', async function(){
let textArea = document.querySelector("textarea");
var taBlob = new Blob([textArea.value], {type: 'text/plain'});
const pickerOptions = {
suggestedName: `${name.toLowerCase()}.txt`,
types: [
{
description: 'Simple Text File',
accept: {
'text/plain': ['.txt'],
},
},
],
};
const fileHandle = await window.showSaveFilePicker(pickerOptions);
const writableFileStream = await fileHandle.createWritable();
await writableFileStream.write(taBlob);
await writableFileStream.close();
});
像往常一样,我们首先在textarea 元素中创建一个text 的blob。我们创建一个对象,包含我们的文件选取器的不同选项,当我们调用showFilePicker() 方法时显示出来。我们可以在这里建议一个名字来保存文件,也可以传递一个允许保存的文件类型数组。该方法返回一个FileSystemFileHandle ,在此基础上我们可以调用createWritable() 方法。
createWritable() 方法创建了一个可写流,我们将之前创建的blob写入这个流中。最后,我们关闭我们的可写流。在这一点上,流中的内容被保存到文件中。
试着在下面CodePen的textarea ,然后点击保存文件按钮,写点东西。该演示在Firefox中无法使用,所以你应该尝试使用Chrome或Edge。
最后的思考
在本教程中,我们学习了在JavaScript中创建和保存文件的三种不同技术。前两种技术要求我们创建锚点标签,并为其href 和download 属性赋值。最后一种技术涉及到使用文件系统访问API,它让我们更好地控制这个过程的不同方面,比如在用户允许的情况下改变默认下载位置。然而,它目前并没有大量的浏览器支持,无法在实际项目中使用。