JavaScript 实现前端文件下载
<h2 id="h2_1">A.download</h2><p>HTML5的A标签有一个<code>download</code>属性,可以告诉浏览器下载而非预览文件,很实用,参考链接:http://www.zhangxinxu.com/wordpress/2016/04/know-about-html-download-attribute/</p>
<p>有时候,WEB端临时创建了一个文件,供用户下载,怎么办呢?示例如下:</p>
<pre><code class="hljs javascript"><span class="hljs-comment">// 从canvas提取图片数据
<span class="hljs-keyword">var raw = ctx.getImageData(<span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-number">300, <span class="hljs-number">300);
<span class="hljs-comment">// 压缩为JPEG图片
<span class="hljs-comment">// https://github.com/owencm/javascript-jpeg-encoder
<span class="hljs-keyword">var jpegURI = (<span class="hljs-keyword">new JPEGEncoder()).encode(raw, <span class="hljs-number">75);
<span class="hljs-comment">// 弹出对话框,交由用户保存图片
saveFile(jpegURI, <span class="hljs-string">'文件名');
<span class="hljs-comment">// saveFile函数
<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">saveFile(<span class="hljs-params">d, a) {
<span class="hljs-keyword">var b = <span class="hljs-built_in">document.createElement(<span class="hljs-string">'a');
b.href = d;
b.download = a;
<span class="hljs-keyword">var c = <span class="hljs-built_in">document.createEvent(<span class="hljs-string">"MouseEvents");
c.initMouseEvent(<span class="hljs-string">"click", <span class="hljs-literal">true, <span class="hljs-literal">false, <span class="hljs-built_in">window, <span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-number">0, <span class="hljs-literal">false, <span class="hljs-literal">false, <span class="hljs-literal">false, <span class="hljs-literal">false, <span class="hljs-number">0, <span class="hljs-literal">null);
b.dispatchEvent(c);
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code><br><br></pre>
<h2 id="h2_2">FileSaver.js</h2>
<p>这是另一种方案,效果也不错。这里推荐FileSaver.js</p>
<p>https://github.com/ChenWenBrian/FileSaver.js</p>
<p>调用方法:</p>
<p>var blob = new Blob(, {type: "text/plain;charset=utf-8"});</p>
<p>saveAs(blob, "content.csv");</p>
<p>这里还有一段原作者的博文。</p>
<p>最后,贴出JS便于查看:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> FileSaver.js
* A saveAs() FileSaver implementation.
* 1.1.20151003
*
* By Eli Grey, http://eligrey.com
* License: MIT
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">global self </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> saveAs = saveAs || (<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(view) {
</span>"use strict"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> IE <10 is explicitly unsupported</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> navigator !== "undefined" && /MSIE \./<span style="color: rgba(0, 0, 0, 1)">.test(navigator.userAgent)) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
doc </span>=<span style="color: rgba(0, 0, 0, 1)"> view.document
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> only get URL when necessary in case Blob.js hasn't overridden it yet</span>
, get_URL = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> view.URL || view.webkitURL ||<span style="color: rgba(0, 0, 0, 1)"> view;
}
, save_link </span>= doc.createElementNS("http://www.w3.org/1999/xhtml", "a"<span style="color: rgba(0, 0, 0, 1)">)
, can_use_save_link </span>= "download" <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> save_link
, click </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(node) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> event = <span style="color: rgba(0, 0, 255, 1)">new</span> MouseEvent("click"<span style="color: rgba(0, 0, 0, 1)">);
node.dispatchEvent(event);
}
, is_safari </span>= /Version\/[\d\.]+.*Safari/<span style="color: rgba(0, 0, 0, 1)">.test(navigator.userAgent)
, webkit_req_fs </span>=<span style="color: rgba(0, 0, 0, 1)"> view.webkitRequestFileSystem
, req_fs </span>= view.requestFileSystem || webkit_req_fs ||<span style="color: rgba(0, 0, 0, 1)"> view.mozRequestFileSystem
, throw_outside </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ex) {
(view.setImmediate </span>|| view.setTimeout)(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span><span style="color: rgba(0, 0, 0, 1)"> ex;
}, </span>0<span style="color: rgba(0, 0, 0, 1)">);
}
, force_saveable_type </span>= "application/octet-stream"<span style="color: rgba(0, 0, 0, 1)">
, fs_min_size </span>= 0
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> for the reasoning behind the timeout and revocation flow</span>
, arbitrary_revoke_timeout = 500 <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> in ms</span>
, revoke = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(file) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> revoker = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> file === "string") { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> file is an object URL</span>
<span style="color: rgba(0, 0, 0, 1)"> get_URL().revokeObjectURL(file);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span> { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> file is a File</span>
<span style="color: rgba(0, 0, 0, 1)"> file.remove();
}
};
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (view.chrome) {
revoker();
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
setTimeout(revoker, arbitrary_revoke_timeout);
}
}
, dispatch </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(filesaver, event_types, event) {
event_types </span>=<span style="color: rgba(0, 0, 0, 1)"> [].concat(event_types);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> i =<span style="color: rgba(0, 0, 0, 1)"> event_types.length;
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (i--<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> listener = filesaver["on" +<span style="color: rgba(0, 0, 0, 1)"> event_types];
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> listener === "function"<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
listener.call(filesaver, event </span>||<span style="color: rgba(0, 0, 0, 1)"> filesaver);
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (ex) {
throw_outside(ex);
}
}
}
}
, auto_bom </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(blob) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> prepend BOM for UTF-8 XML and text/* types (including HTML)</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/<span style="color: rgba(0, 0, 0, 1)">i.test(blob.type)) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Blob(["\ufeff"<span style="color: rgba(0, 0, 0, 1)">, blob], {type: blob.type});
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> blob;
}
, FileSaver </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(blob, name, no_auto_bom) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">no_auto_bom) {
blob </span>=<span style="color: rgba(0, 0, 0, 1)"> auto_bom(blob);
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> First try a.download, then web filesystem, then object URLs</span>
<span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
filesaver </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">
, type </span>=<span style="color: rgba(0, 0, 0, 1)"> blob.type
, blob_changed </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
, object_url
, target_view
, dispatch_all </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
dispatch(filesaver, </span>"writestart progress write writeend".split(" "<span style="color: rgba(0, 0, 0, 1)">));
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> on any filesys errors revert to saving with object URLs</span>
, fs_error = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (target_view && is_safari && <span style="color: rgba(0, 0, 255, 1)">typeof</span> FileReader !== "undefined"<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Safari doesn't allow downloading of blob urls</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> reader = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FileReader();
reader.onloadend </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> base64Data =<span style="color: rgba(0, 0, 0, 1)"> reader.result;
target_view.location.href </span>= "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/<span style="color: rgba(0, 0, 0, 1)">));
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE;
dispatch_all();
};
reader.readAsDataURL(blob);
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.INIT;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> don't create more object URLs than needed</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (blob_changed || !<span style="color: rgba(0, 0, 0, 1)">object_url) {
object_url </span>=<span style="color: rgba(0, 0, 0, 1)"> get_URL().createObjectURL(blob);
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (target_view) {
target_view.location.href </span>=<span style="color: rgba(0, 0, 0, 1)"> object_url;
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> new_tab = view.open(object_url, "_blank"<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (new_tab == undefined &&<span style="color: rgba(0, 0, 0, 1)"> is_safari) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Apple do not allow window.open, see http://bit.ly/1kZffRI</span>
view.location.href =<span style="color: rgba(0, 0, 0, 1)"> object_url
}
}
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE;
dispatch_all();
revoke(object_url);
}
, abortable </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(func) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (filesaver.readyState !==<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> func.apply(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">, arguments);
}
};
}
, create_if_not_found </span>= {create: <span style="color: rgba(0, 0, 255, 1)">true</span>, exclusive: <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">}
, slice
;
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.INIT;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">name) {
name </span>= "download"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (can_use_save_link) {
object_url </span>=<span style="color: rgba(0, 0, 0, 1)"> get_URL().createObjectURL(blob);
save_link.href </span>=<span style="color: rgba(0, 0, 0, 1)"> object_url;
save_link.download </span>=<span style="color: rgba(0, 0, 0, 1)"> name;
setTimeout(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
click(save_link);
dispatch_all();
revoke(object_url);
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE;
});
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Object and web filesystem URLs have a problem saving in Google Chrome when</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> viewed in a tab, so I force save with application/octet-stream</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> http://code.google.com/p/chromium/issues/detail?id=91158</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Update: Google errantly closed 91158, I submitted it again:</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> https://code.google.com/p/chromium/issues/detail?id=389642</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (view.chrome && type && type !==<span style="color: rgba(0, 0, 0, 1)"> force_saveable_type) {
slice </span>= blob.slice ||<span style="color: rgba(0, 0, 0, 1)"> blob.webkitSlice;
blob </span>= slice.call(blob, 0<span style="color: rgba(0, 0, 0, 1)">, blob.size, force_saveable_type);
blob_changed </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Since I can't be sure that the guessed media type will trigger a download</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> in WebKit, I append .download to the filename.</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> https://bugs.webkit.org/show_bug.cgi?id=65440</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (webkit_req_fs && name !== "download"<span style="color: rgba(0, 0, 0, 1)">) {
name </span>+= ".download"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (type === force_saveable_type ||<span style="color: rgba(0, 0, 0, 1)"> webkit_req_fs) {
target_view </span>=<span style="color: rgba(0, 0, 0, 1)"> view;
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">req_fs) {
fs_error();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
fs_min_size </span>+=<span style="color: rgba(0, 0, 0, 1)"> blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(fs) {
fs.root.getDirectory(</span>"saved", create_if_not_found, abortable(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(dir) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> save = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
dir.getFile(name, create_if_not_found, abortable(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(file) {
file.createWriter(abortable(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(writer) {
writer.onwriteend </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(event) {
target_view.location.href </span>=<span style="color: rgba(0, 0, 0, 1)"> file.toURL();
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE;
dispatch(filesaver, </span>"writeend"<span style="color: rgba(0, 0, 0, 1)">, event);
revoke(file);
};
writer.onerror </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> error =<span style="color: rgba(0, 0, 0, 1)"> writer.error;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (error.code !==<span style="color: rgba(0, 0, 0, 1)"> error.ABORT_ERR) {
fs_error();
}
};
</span>"writestart progress write abort".split(" ").forEach(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(event) {
writer[</span>"on" + event] = filesaver["on" +<span style="color: rgba(0, 0, 0, 1)"> event];
});
writer.write(blob);
filesaver.abort </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
writer.abort();
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE;
};
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {create: </span><span style="color: rgba(0, 0, 255, 1)">false</span>}, abortable(<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(file) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> delete file if it already exists</span>
<span style="color: rgba(0, 0, 0, 1)"> file.remove();
save();
}), abortable(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(ex) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ex.code ===<span style="color: rgba(0, 0, 0, 1)"> ex.NOT_FOUND_ERR) {
save();
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
fs_error();
}
}));
}), fs_error);
}), fs_error);
}
, FS_proto </span>=<span style="color: rgba(0, 0, 0, 1)"> FileSaver.prototype
, saveAs </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(blob, name, no_auto_bom) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> FileSaver(blob, name, no_auto_bom);
}
;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> IE 10+ (native saveAs)</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> navigator !== "undefined" &&<span style="color: rgba(0, 0, 0, 1)"> navigator.msSaveOrOpenBlob) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(blob, name, no_auto_bom) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">no_auto_bom) {
blob </span>=<span style="color: rgba(0, 0, 0, 1)"> auto_bom(blob);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> navigator.msSaveOrOpenBlob(blob, name || "download"<span style="color: rgba(0, 0, 0, 1)">);
};
}
FS_proto.abort </span>= <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> filesaver = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;
filesaver.readyState </span>=<span style="color: rgba(0, 0, 0, 1)"> filesaver.DONE;
dispatch(filesaver, </span>"abort"<span style="color: rgba(0, 0, 0, 1)">);
};
FS_proto.readyState </span>= FS_proto.INIT = 0<span style="color: rgba(0, 0, 0, 1)">;
FS_proto.WRITING </span>= 1<span style="color: rgba(0, 0, 0, 1)">;
FS_proto.DONE </span>= 2<span style="color: rgba(0, 0, 0, 1)">;
FS_proto.error </span>=<span style="color: rgba(0, 0, 0, 1)">
FS_proto.onwritestart </span>=<span style="color: rgba(0, 0, 0, 1)">
FS_proto.onprogress </span>=<span style="color: rgba(0, 0, 0, 1)">
FS_proto.onwrite </span>=<span style="color: rgba(0, 0, 0, 1)">
FS_proto.onabort </span>=<span style="color: rgba(0, 0, 0, 1)">
FS_proto.onerror </span>=<span style="color: rgba(0, 0, 0, 1)">
FS_proto.onwriteend </span>=
<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> saveAs;
}(
</span><span style="color: rgba(0, 0, 255, 1)">typeof</span> self !== "undefined" &&<span style="color: rgba(0, 0, 0, 1)"> self
</span>|| <span style="color: rgba(0, 0, 255, 1)">typeof</span> window !== "undefined" &&<span style="color: rgba(0, 0, 0, 1)"> window
</span>|| <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.content
));
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> `self` is undefined in Firefox for Android content script context</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> while `this` is nsIContentFrameMessageManager</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> with an attribute `content` that corresponds to the window</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> module !== "undefined" &&<span style="color: rgba(0, 0, 0, 1)"> module.exports) {
module.exports.saveAs </span>=<span style="color: rgba(0, 0, 0, 1)"> saveAs;
} </span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ((<span style="color: rgba(0, 0, 255, 1)">typeof</span> define !== "undefined" && define !== <span style="color: rgba(0, 0, 255, 1)">null</span>) && (define.amd != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)) {
define([], </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> saveAs;
});
}</span></pre>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/tiandi/p/12830733.html
頁:
[1]