1. Learning objectives
- Understand the core implementation of fileSaver.js
- Do-it-yourself easy export
- How to use files in Vue
2. Source code debugging
1. fileSave.js library address: https://github.com/eligrey/FileSaver.js
1. git clone https://github.com/eligrey/FileSaver.js.git 2. cd FileSaver.js-master/src directory 3. Create a new test.html under src, copy the code below <!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">Download</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 directory structure
3. Open test.html in the browser, click the download button, and debug the code
After entering the saveAs function, you can press the next step to debug and view the code execution process.
fileSaver.js core code implementation
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; // handle string type binary if (typeof blob === "string") {<!-- --> //... a.href = blob; click(a); // Trigger the click method of the a anchor } else {<!-- --> // Process pictures, file types binary a.href = URL.createObjectURL(blob); setTimeout(function () {<!-- --> URL.revokeObjectURL(a.href); }, 4e4); // 40s click(a); } };
4. One of the powerful points of fileSaver is that it is compatible with mainstream browsers. The following is my simple copy version, which omits the consideration of browser compatibility.
/** * Copy FileSaver.js file saving method */ 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 & amp; & amp; xhr.status <= 299; } // Trigger the click method of the a anchor point function click(node) {<!-- --> try {<!-- --> //dispatchEvent dispatches Event to the specified event target node.dispatchEvent(new MouseEvent("click")); } catch (e) {<!-- --> // document.createEvent also creates an event object. 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() can create any type of event object, and the application scenario is more complex //new MouseEvent() can only create mouse event objects } 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(); } // Initialize the environment and determine the top-level object const_global = typeof window !== "undefined" & amp; & amp; window.window === window ? window : typeof self === "object" & amp; & amp; self.self === self ? self : typeof global === "object" & amp; & amp; global.global === global ?global : this; const saveAs = function (blob, name, opts) {<!-- --> var URL = _global.URL; // window.URL in browser // document.createElementNS creates an element with the specified namespace URI and qualified name //Create an element without specifying a namespace URI, use the createElement method var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); name = name || blob.name || "download"; a.download = name; a.rel = "noopener"; // string type binary 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 {<!-- --> // Create a DOMString a.href = URL.createObjectURL(blob); setTimeout(function () {<!-- --> URL.revokeObjectURL(a.href); }, 4000); setTimeout(function () {<!-- --> click(a); }, 0); } }; _global. saveAs = saveAs; // Judging that the module is loaded, it is only applicable to the Node.js environment, and cannot be used on the browser side. if (typeof module !== "undefined") {<!-- --> module.exports = saveAs; }
3. Summary
fileSaver.js mentions the globalThis object of ES6, here is a simple extension. There is a top-level object in the JavaScript language, which provides the global environment (that is, the global scope), and all code is run in this environment.
However, top-level objects are not uniform across implementations.
-
In the browser, the top-level object is window, but Node and Web Worker do not have windows.
-
In browsers and Web Workers, self also points to the top-level object, but Node does not have self.
-
In Node, the top-level object is global, but it is not supported in other environments.
In order to be able to get the top-level object in various environments, the same piece of code now generally uses the this keyword, but there are limitations. -
In the global environment, this returns the top-level object. However, in the Node.js module, this returns the current module, and in the ES6 module, this returns undefined.
-
The this in the function, if the function is not run as an object method, but simply as a function, this will point to the top-level object. However, in strict mode, this will return undefined at this time.
-
Regardless of whether it is strict mode or normal mode, new Function(‘return this’)() will always return the global object. However, if the browser uses CSP (Content Security Policy, Content Security Policy), then methods such as eval and new Function may not be available.
Here’s how to get the top-level object
// method one (typeof window !== 'undefined' ? window : (typeof process === 'object' & amp; & amp; typeof require === 'function' & amp; & amp; typeof global === 'object') ?global : this); // Method Two 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'); };
4. Use export files in Vue
Different MIME types are used for exporting different files
import {<!-- --> message } from 'ant-design-vue'; // Export the file, if the binary data is returned by the backend, the request parameter responseType: "blob" must be added to axios 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('exported successfully') }
3.1 List of common MIME types
extension | document type | MIME type | |
---|---|---|---|
.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 code is not readable to normal users (RFC 3023, section 3) text/xml code is not readable to normal users Say readable (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 (if not included video) |
|
.3g2 |
3GPP2 audio/video container | video/3gpp2 audio/3gpp2 (if no video) |
|
.7z |
7-zip archive | application/x-7z-compressed |
|
– | – | ||