0


前端导出文件 | fileSaver.js源码阅读

一、学习目标😀

  1. 了解fileSaver.js核心实现
  2. 自己动手实现简易导出功能
  3. 在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;functiondownLoad(){var blob =newBlob(["Hello, world!"],{ type:"text/plain;charset=utf-8"});debuggersaveAs(blob,"hello world.txt");//aNode.dispatchEvent(new MouseEvent("click"));}</script></html>

2、src目录结构

111111.png

3、在浏览器打开test.html,点击下载按钮,进行代码调试

image.png
进入saveAs函数后可按下一步进行调试,查看代码执行过程。 image.png

fileSaver.js核心代码实现

varsaveAs=function(blob, name, opts){varURL= _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);// 40sclick(a);}};

4、fileSaver强大的一个点在于它兼容了主流的浏览器,下面是我的简易复刻版,省略了对浏览器兼容性考虑,

/**
 * 仿写FileSaver.js文件保存方法
 */functioncorsEnabled(url){var xhr =newXMLHttpRequest();// 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方法functionclick(node){try{//dispatchEvent向指定事件目标派发Event
        node.dispatchEvent(newMouseEvent("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()只能创建鼠标事件对象}functiondownload(url, name, opts){var xhr =newXMLHttpRequest();
    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;constsaveAs=function(blob, name, opts){varURL= _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这些方法都可能无法使用。 下面是获取顶层对象的方法
// 方法一(typeof window !=='undefined'? window
 :(typeof process ==='object'&&typeof require ==='function'&&typeof global ==='object')? global
 :this);// 方法二vargetGlobal=function(){if(typeof self !=='undefined'){return self;}if(typeof window !=='undefined'){return window;}if(typeof global !=='undefined'){return global;}thrownewError('unable to locate global object');};

四、在Vue中使用导出文件😊

导出不同的文件使用的MIME类型也不同

import{ message }from'ant-design-vue';// 导出文件 ,如果二进制数据是后端返回,须在axios添加请求参数 responseType: "blob"exportconstexportFileFun=function(res, name,type='application/vnd.ms-excel',fileSuffix='.xlsx'){let blob =newBlob([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

——

标签: javascript 前端 vue

本文转载自: https://blog.csdn.net/qq_39339805/article/details/130856252
版权归原作者 徐小三 所有, 如有侵权,请联系我们删除。

“前端导出文件 | fileSaver.js源码阅读”的评论:

还没有评论