一、学习目标😀
- 了解fileSaver.js核心实现
- 自己动手实现简易导出功能
- 在Vue中如何使用文件
二、源码调试😊
1、fileSave.js库地址:https://github.com/eligrey/FileSaver.js
1、git clone https://github.com/eligrey/FileSaver.js.git
2、cd FileSaver.js-master/ src 目录
3、在src下新建test.html,copy 下面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn">下载</button>
<a href="www.baidu.com" class="anode"></a>
</body>
<script src="./FileSaver.js"></script>
<script>
console.log(window,'window')
const btn = document.querySelector("#btn");
const aNode = document.querySelector(".anode");
btn.onclick = downLoad;
function downLoad() {
var blob = new Blob(["Hello, world!"], { type: "text/plain;charset=utf-8" });
debugger
saveAs(blob, "hello world.txt");
//aNode.dispatchEvent(new MouseEvent("click"));
}
</script>
</html>
2、src目录结构
3、在浏览器打开test.html,点击下载按钮,进行代码调试
进入saveAs函数后可按下一步进行调试,查看代码执行过程。
fileSaver.js核心代码实现
var saveAs = function (blob, name, opts) {
var URL = _global.URL || _global.webkitURL;
//...
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
a.download = name;
// 处理字符串类型二进制
if (typeof blob === "string") {
//...
a.href = blob;
click(a); // 触发a锚点的click方法
} else {
// 处理图片、文件类型二进制
a.href = URL.createObjectURL(blob);
setTimeout(function () {
URL.revokeObjectURL(a.href);
}, 4e4); // 40s
click(a);
}
};
4、fileSaver强大的一个点在于它兼容了主流的浏览器,下面是我的简易复刻版,省略了对浏览器兼容性考虑,
/**
* 仿写FileSaver.js文件保存方法
*/
function corsEnabled(url) {
var xhr = new XMLHttpRequest();
// use sync to avoid popup blocker
xhr.open("HEAD", url, false);
try {
xhr.send();
} catch (e) {}
console.log(xhr.status,'status')
return xhr.status >= 200 && xhr.status <= 299;
}
// 触发a锚点的click方法
function click(node) {
try {
//dispatchEvent向指定事件目标派发Event
node.dispatchEvent(new MouseEvent("click"));
} catch (e) {
// document.createEvent也是创建事件对象。
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent(
"click",
true,
true,
window,
0,
0,
0,
80,
20,
false,
false,
false,
false,
0,
null
);
node.dispatchEvent(evt);
}
//createEvent()可以创建任何类型的事件对象,应用场景更复杂
//new MouseEvent()只能创建鼠标事件对象
}
function download(url, name, opts) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.onload = function () {
saveAs(xhr.response, name, opts);
};
xhr.onerror = function () {
console.error("could not download file");
};
xhr.send();
}
// 初始化环境,判断顶层对象
const _global =
typeof window !== "undefined" && window.window === window
? window
: typeof self === "object" && self.self === self
? self
: typeof global === "object" && global.global === global
? global
: this;
const saveAs = function (blob, name, opts) {
var URL = _global.URL; // 浏览器中 window.URL
// document.createElementNS 创建一个具有指定命名空间 URI 和限定名称的元素
//创建一个元素而不指定命名空间URI,可使用createElement方法
var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
name = name || blob.name || "download";
a.download = name;
a.rel = "noopener";
// 字符串类型二进制
if (typeof blob === "string") {
a.href = blob;
if (a.origin !== location.origin) {
corsEnabled(a.href) ? download(blob, name, opts) : click(a, (a.target = "_blank"));
} else {
click(a);
}
} else {
// 创建一个DOMString
a.href = URL.createObjectURL(blob);
setTimeout(function () {
URL.revokeObjectURL(a.href);
}, 4000);
setTimeout(function () {
click(a);
}, 0);
}
};
_global.saveAs = saveAs;
// 判断模块被加载,只适用于Node.js环境中,并不能在浏览器端使用。
if (typeof module !== "undefined") {
module.exports = saveAs;
}
三、小结😳
fileSaver.js提到ES6的globalThis对象,这里简单扩展下。JavaScript 语言存在一个顶层对象,它提供全局环境(即全局作用域),所有代码都是在这个环境中运行。
但是,顶层对象在各种实现里面是不统一的。
-
浏览器里面,顶层对象是window,但 Node 和 Web Worker 没有window。
-
浏览器和 Web Worker 里面,self也指向顶层对象,但是 Node 没有self。
-
Node 里面,顶层对象是global,但其他环境都不支持。
同一段代码为了能够在各种环境,都能取到顶层对象,现在一般是使用this关键字,但是有局限性。 -
全局环境中,this会返回顶层对象。但是,Node.js 模块中this返回的是当前模块,ES6 模块中this返回的是undefined。
-
函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。但是,严格模式下,这时this会返回undefined。
-
不管是严格模式,还是普通模式,new Function(‘return this’)(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么eval、new Function这些方法都可能无法使用。
下面是获取顶层对象的方法文章来源:https://www.toymoban.com/news/detail-753240.html
// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};
四、在Vue中使用导出文件😊
导出不同的文件使用的MIME类型也不同文章来源地址https://www.toymoban.com/news/detail-753240.html
import { message } from 'ant-design-vue';
// 导出文件 ,如果二进制数据是后端返回,须在axios添加请求参数 responseType: "blob"
export const exportFileFun = function (res, name,type='application/vnd.ms-excel',fileSuffix='.xlsx') {
let blob = new Blob([res], {
type,
})
let fileName = name + fileSuffix
let link = document.createElement('a')
link.download = fileName
link.href = window.URL.createObjectURL(blob)
document.body.appendChild(link)
link.click()
setTimeout(() => {
window.URL.revokeObjectURL(link.href)
},1000)
message.success('导出成功')
}
3.1常见 MIME 类型列表
扩展名 | 文档类型 | MIME 类型 | |
---|---|---|---|
.aac |
AAC audio | audio/aac |
|
.abw |
AbiWord document | application/x-abiword |
|
.arc |
Archive document (multiple files embedded) | application/x-freearc |
|
.avi |
AVI: Audio Video Interleave | video/x-msvideo |
|
.azw |
Amazon Kindle eBook format | application/vnd.amazon.ebook |
|
.bin |
Any kind of binary data | application/octet-stream |
|
.bmp |
Windows OS/2 Bitmap Graphics | image/bmp |
|
.bz |
BZip archive | application/x-bzip |
|
.bz2 |
BZip2 archive | application/x-bzip2 |
|
.csh |
C-Shell script | application/x-csh |
|
.css |
Cascading Style Sheets (CSS) | text/css |
|
.csv |
Comma-separated values (CSV) | text/csv |
|
.doc |
Microsoft Word | application/msword |
|
.docx |
Microsoft Word (OpenXML) | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
|
.eot |
MS Embedded OpenType fonts | application/vnd.ms-fontobject |
|
.epub |
Electronic publication (EPUB) | application/epub+zip |
|
.gif |
Graphics Interchange Format (GIF) | image/gif |
|
.htm .html |
HyperText Markup Language (HTML) | text/html |
|
.ico |
Icon format | image/vnd.microsoft.icon |
|
.ics |
iCalendar format | text/calendar |
|
.jar |
Java Archive (JAR) | application/java-archive |
|
.jpeg .jpg
|
JPEG images | image/jpeg |
|
.js |
JavaScript | text/javascript |
|
.json |
JSON format | application/json |
|
.jsonld |
JSON-LD format | application/ld+json |
|
.mid .midi
|
Musical Instrument Digital Interface (MIDI) |
audio/midi audio/x-midi
|
|
.mjs |
JavaScript module | text/javascript |
|
.mp3 |
MP3 audio | audio/mpeg |
|
.mpeg |
MPEG Video | video/mpeg |
|
.mpkg |
Apple Installer Package | application/vnd.apple.installer+xml |
|
.odp |
OpenDocument presentation document | application/vnd.oasis.opendocument.presentation |
|
.ods |
OpenDocument spreadsheet document | application/vnd.oasis.opendocument.spreadsheet |
|
.odt |
OpenDocument text document | application/vnd.oasis.opendocument.text |
|
.oga |
OGG audio | audio/ogg |
|
.ogv |
OGG video | video/ogg |
|
.ogx |
OGG | application/ogg |
|
.otf |
OpenType font | font/otf |
|
.png |
Portable Network Graphics | image/png |
|
.pdf |
Adobe Portable Document Format (PDF) | application/pdf |
|
.ppt |
Microsoft PowerPoint | application/vnd.ms-powerpoint |
|
.pptx |
Microsoft PowerPoint (OpenXML) | application/vnd.openxmlformats-officedocument.presentationml.presentation |
|
.rar |
RAR archive | application/x-rar-compressed |
|
.rtf |
Rich Text Format (RTF) | application/rtf |
|
.sh |
Bourne shell script | application/x-sh |
|
.svg |
Scalable Vector Graphics (SVG) | image/svg+xml |
|
.swf |
Small web format (SWF) or Adobe Flash document | application/x-shockwave-flash |
|
.tar |
Tape Archive (TAR) | application/x-tar |
|
.tif .tiff |
Tagged Image File Format (TIFF) | image/tiff |
|
.ttf |
TrueType Font | font/ttf |
|
.txt |
Text, (generally ASCII or ISO 8859-n) | text/plain |
|
.vsd |
Microsoft Visio | application/vnd.visio |
|
.wav |
Waveform Audio Format | audio/wav |
|
.weba |
WEBM audio | audio/webm |
|
.webm |
WEBM video | video/webm |
|
.webp |
WEBP image | image/webp |
|
.woff |
Web Open Font Format (WOFF) | font/woff |
|
.woff2 |
Web Open Font Format (WOFF) | font/woff2 |
|
.xhtml |
XHTML | application/xhtml+xml |
|
.xls |
Microsoft Excel | application/vnd.ms-excel |
|
.xlsx |
Microsoft Excel (OpenXML) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
|
.xml |
XML |
application/xml 代码对普通用户来说不可读 (RFC 3023, section 3) text/xml 代码对普通用户来说可读 (RFC 3023, section 3) |
|
.xul |
XUL | application/vnd.mozilla.xul+xml |
|
.zip |
ZIP archive | application/zip |
|
.3gp |
3GPP audio/video container |
video/3gpp audio/3gpp (若不含视频) |
|
.3g2 |
3GPP2 audio/video container |
video/3gpp2 audio/3gpp2 (若不含视频) |
|
.7z |
7-zip archive | application/x-7z-compressed |
|
— | — | ||
到了这里,关于前端导出文件 | fileSaver.js源码阅读的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!