「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」
下载
通常的两种下载方式是
- 后端给定文件服务器的地址,通过a标签进行下载,
<a href="xxxx" download="tupian.png">点击下载</a>
如果想对文件名进行修改的话,只需要在a标签上添加download属性,指定文件名称;
但是,请注意
a标签download属性只支持谷歌和火狐浏览器,不支持IE(IE不支持html5 新特性a标签download属性)。
同时访问的域名与a标签内href的域名需要一致,如果跨域的话,文件名称就不支持修改了,
这里我推荐一个js库,支持修改文件名称 file-save
- 后端传回blob文件流,前端解析后,通过a标签进行下载,
这里需要注意的是,请求头中必须声明responseType 为 blob 类型
if (navigator.appVersion.toString().indexOf('.NET') > 0) {
window.navigator.msSaveBlob(blob, fileName);
} else {
const href = window.URL.createObjectURL(blob); // 创建下载的链接
downloadElement.href = href;
downloadElement.download = 'fileName; // 下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); // 点击下载
document.body.removeChild(downloadElement); // 下载完成移除元素
window.URL.revokeObjectURL(href); // 释放掉blob对象
}
以上两种下载方式,文件要么下载时询问下载路径,要么就是浏览器的指定目录
但是,如果要求用户自定义目录呢
这里用到了新的api showSaveFilePicker
showSaveFilePicker
兼容性
老规矩,上兼容性
很明显,由于涉及到读写文件,就会涉及到安全方面的问题,所以,兼容性不高,即使是chrome浏览器,也只是在86版本后才开始兼容,
这个api也是google倡导的,这里大家需要注意的是,因为 Google 的产品策略一向是说关就关,所以大家要留心常看文档,别学了一半 API 没了,
例子
const BtnSaveAs = document.getElementById('btn-save-as')
async function fileSaveAs(description) {
const options = {
types: [{
description,
accept: {
'text/plain': ['.txt'],
},
}, ],
};
return await window.showSaveFilePicker(options);
}
BtnSaveAs.addEventListener('click', async () => {
const handle = await fileSaveAs("Hello File Access Api")
})
使用MDN的例子,点击之后,可以选择路径存放文件,但是此时,文件是没有任何数据的,所以我们需要去写入数据
写入数据
async function writeFile(fileHandle, contents) {
// createWritable()创建一个可写流对象WritableStream
const writable = await fileHandle.createWritable();
// 通过管道将数据传输到文件
await writable.write(contents);
// 管道使用完毕后需要关闭
await writable.close();
}
BtnSaveAs.addEventListener('click',async ()=>{
const handle = await fileSaveAs("Hello File Access Api")
await writeFile(handle, data)
})
参数
包含选项的可选对象,如下所示:
excludeAcceptAllOption:Boolean默认false。默认情况下,选择器应包含一个选项以不应用任何文件类型过滤器(由下面的类型选项发起)。将此选项设置为true意味着该选项_不可_用。
suggestedName:String建议的文件名。
startIn:String可选值
-
- desktop: 桌面
-
- documents: 文档
-
- downloads: 下载
-
- music: 音乐
-
- pictures: 图像
-
- videos: 视频
types:Array 允许保存的文件类型。每个项目都是具有以下选项的对象
-
- description:允许的文件类型类别的可选描述。
在vue的使用
write()方法负责写入数据,可以是字符串,Blob对象,也可以是流。
下面例子中返回的是文件流
async mutilDownload() {
const params = {};
const res = await mutilDownload(params);
const handle = await this.fileSaveAs("Hello File Access Api")
await this.writeFile(handle, res.data)
},
推荐库
file-save 将文件保存在节点/浏览器中。在浏览器中它会提示保存文件对话框,在节点中它会创建一个文件
browser-fs-access 它提供了对File Access System API的封装,比较成熟的例子有excalidraw