js实现浏览与保存本地常见文件 (2022.10.24)
Posted jing_zhong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js实现浏览与保存本地常见文件 (2022.10.24)相关的知识,希望对你有一定的参考价值。
js实现浏览与保存本地常见文件 2022.10.24
1、需求分析
在平时的学习和工作中,相信大家会经常遇到这样一个问题:我在阅读网页时遇到一个json文件,保存到本地后需要查看,那么我该选择什么样的IDE来打开这些文件呢?。
此时,为了解决上述问题,一般来说大致有三类解决方案:第一种
,其中最简单的方式是用记事本Notepad
打开,但可能有的小伙伴不喜欢使用Window操作系统自带的记事本查看文本文件,因为没有特定的颜色和变量标识,不利于编码;第二种方式,可以安装一些 IDE文本编辑器
来打开文件进行编辑;第三种,同时也是我认为较好的方方法,尤其对于比较懒的一些工程师或者开发者而言,浏览器Browser
往往是最快捷、最普遍、最简单的文件查看器。
2、使用js方法介绍
为了编写javascript
代码来加载和保存本地文件,我们需要进行文件的读取操作,即文件读取和文件写入,具体涉及到的方法就是FileSaver
和FileReader
。
2.1 FileSaver.js 简介
FileSaver是一种在客户端保存文件的解决方案,并且具有非常完美的应用表现,尤其是客户端Web应用的文件生成方面。它支持的浏览器包括Firefox、Chrome、Edge、IE、Opera 和 Safari
。
|
FileSaver.js
文件内容
(function (global, factory)
if (typeof define === "function" && define.amd)
define([], factory);
else if (typeof exports !== "undefined")
factory();
else
var mod =
exports:
;
factory();
global.FileSaver = mod.exports;
)(this, function ()
"use strict";
/*
* FileSaver.js
* A saveAs() FileSaver implementation.
*
* By Eli Grey, http://eligrey.com
*
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
* source : http://purl.eligrey.com/github/FileSaver.js
*/
// The one and only way of getting global scope in all environments
// https://stackoverflow.com/q/3277182/1008999
var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;
function bom(blob, opts)
if (typeof opts === 'undefined') opts =
autoBom: false
;else if (typeof opts !== 'object')
console.warn('Deprecated: Expected third argument to be a object');
opts =
autoBom: !opts
;
// prepend BOM for UTF-8 XML and text/* types (including html)
// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
if (opts.autoBom && /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type))
return new Blob([String.fromCharCode(0xFEFF), blob],
type: blob.type
);
return blob;
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();
function corsEnabled(url)
var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
xhr.open('HEAD', url, false);
try
xhr.send();
catch (e)
return xhr.status >= 200 && xhr.status <= 299;
// `a.click()` doesn't work for all browsers (#465)
function click(node)
try
node.dispatchEvent(new MouseEvent('click'));
catch (e)
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);
// Detect WebView inside a native macOS app by ruling out all browsers
// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
var isMacOSWebView = /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent);
var saveAs = _global.saveAs || ( // probably in some web worker
typeof window !== 'object' || window !== _global ? function saveAs()
/* noop */
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
: 'download' in HTMLAnchorElement.prototype && !isMacOSWebView ? function saveAs(blob, name, opts)
var URL = _global.URL || _global.webkitURL;
var a = document.createElement('a');
name = name || blob.name || 'download';
a.download = name;
a.rel = 'noopener'; // tabnabbing
// TODO: detect chrome extensions & packaged apps
// a.target = '_blank'
if (typeof blob === 'string')
// Support regular links
a.href = blob;
if (a.origin !== location.origin)
corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
else
click(a);
else
// Support blobs
a.href = URL.createObjectURL(blob);
setTimeout(function ()
URL.revokeObjectURL(a.href);
, 4E4); // 40s
setTimeout(function ()
click(a);
, 0);
// Use msSaveOrOpenBlob as a second approach
: 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts)
name = name || blob.name || 'download';
if (typeof blob === 'string')
if (corsEnabled(blob))
download(blob, name, opts);
else
var a = document.createElement('a');
a.href = blob;
a.target = '_blank';
setTimeout(function ()
click(a);
);
else
navigator.msSaveOrOpenBlob(bom(blob, opts), name);
// Fallback to using FileReader and a popup
: function saveAs(blob, name, opts, popup)
// Open a popup immediately do go around popup blocker
// Mostly only available on user interaction and the fileReader is async so...
popup = popup || open('', '_blank');
if (popup)
popup.document.title = popup.document.body.innerText = 'downloading...';
if (typeof blob === 'string') return download(blob, name, opts);
var force = blob.type === 'application/octet-stream';
var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
var isChromeios = /CriOS\\/[\\d]+/.test(navigator.userAgent);
if ((isChromeIOS || force && isSafari || isMacOSWebView) && typeof FileReader !== 'undefined')
// Safari doesn't allow downloading of blob URLs
var reader = new FileReader();
reader.onloadend = function ()
var url = reader.result;
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
if (popup) popup.location.href = url;else location = url;
popup = null; // reverse-tabnabbing #460
;
reader.readAsDataURL(blob);
else
var URL = _global.URL || _global.webkitURL;
var url = URL.createObjectURL(blob);
if (popup) popup.location = url;else location.href = url;
popup = null; // reverse-tabnabbing #460
setTimeout(function ()
URL.revokeObjectURL(url);
, 4E4); // 40s
);
_global.saveAs = saveAs.saveAs = saveAs;
if (typeof module !== 'undefined')
module.exports = saveAs;
);
2.1.1 FileSaver的import引入(Node环境)
在Vue
等大型项目当中,一般通过npm
安装FileSaver
,输入命令npm install file-saver --save,推荐使用import方式导入js类库,然后进行相关方法的调用,具体如下:
import saveAs from 'file-saver';
2.1.2 FileSaver的script引入(HTML文件)
如果要在html
文档中使用FileSaver
库,那么仅仅在script
标签中引入对应的js文件即可,具体如下:
<script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.js"></script>
2.1.3 FileSaver的调用方法
var file = new File(["Hello, world!"], "hello world.txt", type: "text/plain;charset=utf-8");
FileSaver.saveAs(file);
// 保存txt文件
var blob = new Blob(["Hello, world!"], type: "text/plain;charset=utf-8");
FileSaver.saveAs(blob, "hello world.txt");
//保存 URL
FileSaver.saveAs("https://httpbin.org/image", "image.jpg");
//保存 canvas
var canvas = document.getElementById("my-canvas");
canvas.toBlob(function(blob)
saveAs(blob, "pretty image.png");
);
当然,如果想要保存网络文件,可以参考Saving a remote file。
2.2 FileReader
这里使用FileReader来对本地磁盘文件进行读取操作,
2.2.1 检测浏览器是否支持FileReader的js函数
function detect_FileReader()
if (window.FileReader)
var fr = new FileReader();
return true;
else
return false;
2.2.2 Blob.js
下面放置了Blob.js
文件的代码,里面介绍了Blob
、File
及FileReader的
相关构造器实现,可供感兴趣的开发者参考查看,受益匪浅。
Blob.js
文件内容:
/* Blob.js
* A Blob, File, FileReader & URL implementation.
* 2019-04-19
*
* By Eli Grey, http://eligrey.com
* By Jimmy Wärting, https://github.com/jimmywarting
* License: MIT
* See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
*/
;(function ()
var global = typeof window === 'object'
? window : typeof self === 'object'
? self : this
var BlobBuilder = global.BlobBuilder
|| global.WebKitBlobBuilder
|| global.MSBlobBuilder
|| global.MozBlobBuilder
global.URL = global.URL || global.webkitURL || function (href, a)
a = document.createElement('a')
a.href = href
return a
var origBlob = global.Blob
var createObjectURL = URL.createObjectURL
var revokeObjectURL = URL.revokeObjectURL
var strTag = global.Symbol && global.Symbol.toStringTag
var blobSupported = false
var blobSupportsArrayBufferView = false
var arrayBufferSupported = !!global.ArrayBuffer
var blobBuilderSupported = BlobBuilder
&& BlobBuilder.prototype.append
&& BlobBuilder.prototype.getBlob
try
// Check if Blob constructor is supported
blobSupported = new Blob(['ä']).size === 2
// Check if Blob constructor supports ArrayBufferViews
// Fails in Safari 6, so we need to map to ArrayBuffers there.
blobSupportsArrayBufferView = new Blob([new Uint8Array([1, 2])]).size === 2
catch (e)
/**
* Helper function that maps ArrayBufferViews to ArrayBuffers
* Used by BlobBuilder constructor and old browsers that didn't
* support it in the Blob constructor.
*/
function mapArrayBufferViews (ary)
return ary.map(function (chunk)
if (chunk.buffer instanceof ArrayBuffer)
var buf = chunk.buffer
// if this is a subarray, make a copy so we only
// include the subarray region from the underlying buffer
if (chunk.byteLength !== buf.byteLength)
var copy = new Uint8Array(chunk.byteLength)
copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength))
buf = copy.buffer
return buf
return chunk
)
function BlobBuilderConstructor (ary, options)
options = options ||
var bb = new BlobBuilder()
mapArrayBufferViews(ary).forEach(function (part)
bb.append(part)
)
return options.type ? bb.getBlob(options.type) : bb.getBlob()
function BlobConstructor (ary, options)
return new origBlob(mapArrayBufferViews(ary), options || )
if (global.Blob)
BlobBuilderConstructor.prototype = Blob.prototype
BlobConstructor.prototype = Blob.prototype
/********************************************************/
/* String Encoder fallback */
/********************************************************/
function stringEncode (js怎么把id存到浏览器本地