A.download

HTML5的A标签有一个download属性,可以告诉浏览器下载而非预览文件,很实用,参考链接:http://www.zhangxinxu.com/wordpress/2016/04/know-about-html-download-attribute/

有时候,WEB端临时创建了一个文件,供用户下载,怎么办呢?示例如下:

// 从canvas提取图片数据
var raw = ctx.getImageData(0, 0, 300, 300);
// 压缩为JPEG图片
// https://github.com/owencm/javascript-jpeg-encoder
var jpegURI = (new JPEGEncoder()).encode(raw, 75);
// 弹出对话框,交由用户保存图片
saveFile(jpegURI, '文件名'); // saveFile函数
function saveFile(d, a) {
var b = document.createElement('a');
b.href = d;
b.download = a;
var c = document.createEvent("MouseEvents");
c.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
b.dispatchEvent(c);
}


FileSaver.js

这是另一种方案,效果也不错。这里推荐FileSaver.js

https://github.com/ChenWenBrian/FileSaver.js

调用方法:

var blob = new Blob([content], {type: "text/plain;charset=utf-8"});

saveAs(blob, "content.csv");

这里还有一段原作者的博文。

最后,贴出JS便于查看:

/* 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
*/ /*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ var saveAs = saveAs || (function(view) {
"use strict";
// IE <10 is explicitly unsupported
if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
return;
}
var
doc = view.document
// only get URL when necessary in case Blob.js hasn't overridden it yet
, get_URL = function() {
return view.URL || view.webkitURL || view;
}
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
, can_use_save_link = "download" in save_link
, click = function(node) {
var event = new MouseEvent("click");
node.dispatchEvent(event);
}
, is_safari = /Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
, webkit_req_fs = view.webkitRequestFileSystem
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
, throw_outside = function(ex) {
(view.setImmediate || view.setTimeout)(function() {
throw ex;
}, 0);
}
, force_saveable_type = "application/octet-stream"
, fs_min_size = 0
// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
// for the reasoning behind the timeout and revocation flow
, arbitrary_revoke_timeout = 500 // in ms
, revoke = function(file) {
var revoker = function() {
if (typeof file === "string") { // file is an object URL
get_URL().revokeObjectURL(file);
} else { // file is a File
file.remove();
}
};
if (view.chrome) {
revoker();
} else {
setTimeout(revoker, arbitrary_revoke_timeout);
}
}
, dispatch = function(filesaver, event_types, event) {
event_types = [].concat(event_types);
var i = event_types.length;
while (i--) {
var listener = filesaver["on" + event_types[i]];
if (typeof listener === "function") {
try {
listener.call(filesaver, event || filesaver);
} catch (ex) {
throw_outside(ex);
}
}
}
}
, auto_bom = function(blob) {
// prepend BOM for UTF-8 XML and text/* types (including HTML)
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
return new Blob(["\ufeff", blob], {type: blob.type});
}
return blob;
}
, FileSaver = function(blob, name, no_auto_bom) {
if (!no_auto_bom) {
blob = auto_bom(blob);
}
// First try a.download, then web filesystem, then object URLs
var
filesaver = this
, type = blob.type
, blob_changed = false
, object_url
, target_view
, dispatch_all = function() {
dispatch(filesaver, "writestart progress write writeend".split(" "));
}
// on any filesys errors revert to saving with object URLs
, fs_error = function() {
if (target_view && is_safari && typeof FileReader !== "undefined") {
// Safari doesn't allow downloading of blob urls
var reader = new FileReader();
reader.onloadend = function() {
var base64Data = reader.result;
target_view.location.href = "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/));
filesaver.readyState = filesaver.DONE;
dispatch_all();
};
reader.readAsDataURL(blob);
filesaver.readyState = filesaver.INIT;
return;
}
// don't create more object URLs than needed
if (blob_changed || !object_url) {
object_url = get_URL().createObjectURL(blob);
}
if (target_view) {
target_view.location.href = object_url;
} else {
var new_tab = view.open(object_url, "_blank");
if (new_tab == undefined && is_safari) {
//Apple do not allow window.open, see http://bit.ly/1kZffRI
view.location.href = object_url
}
}
filesaver.readyState = filesaver.DONE;
dispatch_all();
revoke(object_url);
}
, abortable = function(func) {
return function() {
if (filesaver.readyState !== filesaver.DONE) {
return func.apply(this, arguments);
}
};
}
, create_if_not_found = {create: true, exclusive: false}
, slice
;
filesaver.readyState = filesaver.INIT;
if (!name) {
name = "download";
}
if (can_use_save_link) {
object_url = get_URL().createObjectURL(blob);
save_link.href = object_url;
save_link.download = name;
setTimeout(function() {
click(save_link);
dispatch_all();
revoke(object_url);
filesaver.readyState = filesaver.DONE;
});
return;
}
// Object and web filesystem URLs have a problem saving in Google Chrome when
// viewed in a tab, so I force save with application/octet-stream
// http://code.google.com/p/chromium/issues/detail?id=91158
// Update: Google errantly closed 91158, I submitted it again:
// https://code.google.com/p/chromium/issues/detail?id=389642
if (view.chrome && type && type !== force_saveable_type) {
slice = blob.slice || blob.webkitSlice;
blob = slice.call(blob, 0, blob.size, force_saveable_type);
blob_changed = true;
}
// Since I can't be sure that the guessed media type will trigger a download
// in WebKit, I append .download to the filename.
// https://bugs.webkit.org/show_bug.cgi?id=65440
if (webkit_req_fs && name !== "download") {
name += ".download";
}
if (type === force_saveable_type || webkit_req_fs) {
target_view = view;
}
if (!req_fs) {
fs_error();
return;
}
fs_min_size += blob.size;
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
var save = function() {
dir.getFile(name, create_if_not_found, abortable(function(file) {
file.createWriter(abortable(function(writer) {
writer.onwriteend = function(event) {
target_view.location.href = file.toURL();
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "writeend", event);
revoke(file);
};
writer.onerror = function() {
var error = writer.error;
if (error.code !== error.ABORT_ERR) {
fs_error();
}
};
"writestart progress write abort".split(" ").forEach(function(event) {
writer["on" + event] = filesaver["on" + event];
});
writer.write(blob);
filesaver.abort = function() {
writer.abort();
filesaver.readyState = filesaver.DONE;
};
filesaver.readyState = filesaver.WRITING;
}), fs_error);
}), fs_error);
};
dir.getFile(name, {create: false}, abortable(function(file) {
// delete file if it already exists
file.remove();
save();
}), abortable(function(ex) {
if (ex.code === ex.NOT_FOUND_ERR) {
save();
} else {
fs_error();
}
}));
}), fs_error);
}), fs_error);
}
, FS_proto = FileSaver.prototype
, saveAs = function(blob, name, no_auto_bom) {
return new FileSaver(blob, name, no_auto_bom);
}
;
// IE 10+ (native saveAs)
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
return function(blob, name, no_auto_bom) {
if (!no_auto_bom) {
blob = auto_bom(blob);
}
return navigator.msSaveOrOpenBlob(blob, name || "download");
};
} FS_proto.abort = function() {
var filesaver = this;
filesaver.readyState = filesaver.DONE;
dispatch(filesaver, "abort");
};
FS_proto.readyState = FS_proto.INIT = 0;
FS_proto.WRITING = 1;
FS_proto.DONE = 2; FS_proto.error =
FS_proto.onwritestart =
FS_proto.onprogress =
FS_proto.onwrite =
FS_proto.onabort =
FS_proto.onerror =
FS_proto.onwriteend =
null; return saveAs;
}(
typeof self !== "undefined" && self
|| typeof window !== "undefined" && window
|| this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window if (typeof module !== "undefined" && module.exports) {
module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
define([], function() {
return saveAs;
});
}

JavaScript 实现前端文件下载的更多相关文章

  1. Javascript实现前端简单路由

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ...

  2. JST(JavaScript Trimpath)前端模板引擎简介

    JST(JavaScript Trimpath)前端模板引擎简介及应用 今天在做某系统日志列表的时候用到了这个玩意儿.刚开始只是根据别人的例子照葫芦画瓢完成了日志列表及对应详情,晚上有空了才仔细去网上 ...

  3. PDF.Js的使用—javascript中前端显示pdf文件

    PDF.Js的使用—javascript中前端显示pdf文件 写于2018/12/6 起因是一个图片展示页面需要展示pdf格式的文件,所以查了半天决定使用pdf.js,我也不求有多了解它,能实现我想要 ...

  4. 使用Javascript监控前端相关数据

    项目开发完成外发后,没有一个监控系统,我们很难了解到发布出去的代码在用户机器上执行是否正确,所以需要建立前端代码性能相关的监控系统. 所以我们需要做以下的一些模块: 一.收集脚本执行错误 functi ...

  5. 【JS】前端文件下载(无刷新)方法总结

    #传统方法 利用iframe 或 form.submit 或 windows.open直接向后端发请求,后端返回文件流,后端处理成功后会直接返回到页面,浏览器会整理并打开自己的保存下载文件机制 . 1 ...

  6. JAVAScript:前端模块化开发

    目录 一:前端模块化概要 1.1.模块化概要 1.2.函数封装 1.3.对象封装 1.4.立即执行函数表达式(IIFE) 1.5.模块化规范 1.5.1.CommonJS 1.5.2.AMD((Asy ...

  7. 七牛云存储的 Javascript Web 前端文件上传

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,七牛云存储的 Web 前端文件上传 七牛是不错的云存储产品,特别是有免费的配额可 ...

  8. 如何用JavaScript判断前端应用运行环境(移动平台还是桌面环境)

    我们部署在某些云平台或者Web服务器上的前端应用,既可以用PC端浏览器访问,也可以用手机上的浏览器访问. 在前端应用里,有时候我们需要根据运行环境的不同做出对应处理.比如下面这段逻辑,如果判断出应用当 ...

  9. 如何使用JavaScript实现前端导入和导出excel文件

    一.SpreadJS 简介 SpreadJS 是一款基于 HTML5 的纯 JavaScript 电子表格和网格功能控件,以“高速低耗.纯前端.零依赖”为产品特色,可嵌入任何操作系统,同时满足 .NE ...

  10. 【JavaScript】前端插件

    树形结构: http://www.jeasyui.com/documentation/index.php 网上有对这个插件的说明,总的来说这个插件将selected和checked作为两种状态: 1. ...

随机推荐

  1. ArrayList,LinkedList,Vector三者的区别

    List 中元素是有序的,元素可以重复,因为该集合体有索引 ArrayList: 底层数据结构是数组,查询快,增删慢. 线程不安全,效率高. 当元素放满了后,默认以原长度的 50%+1 的长度加长集合 ...

  2. 直播预告丨 OpenHarmony 标准系统多媒体子系统之相机解读

    5 月 26日(周四)晚上 19 点,OpenHarmony 开源开发者成长计划知识赋能第五期"掌握 OpenHarmony 多媒体的框架原理"的第六节直播课,即将开播! 深开鸿资 ...

  3. R语言学习1:基本数据类型,文件读取

    本系列是一个新的系列,在此系列中,我将和大家共同学习R语言.由于我对R语言的了解也甚少,所以本系列更多以一个学习者的视角来完成. 参考教材:<R语言实战>第二版(Robert I.Kaba ...

  4. 国产开源数据库OpenGauss的安装运行

    步骤一:OpenGauss 的安装 环境 OS:openEuler 20.03 64bit with ARM 架构:arm64 部署:单机 安装过程 1.环境配置 安装依赖包: yum install ...

  5. spark 计算前后两条记录之间的差(diff),时间差等

    有时候会遇到这样的场景:有一个datafram,我们需要计算同一组对象中,前后两条记录之间的差值,此处并不仅限于时间,还可以是其他的数据类型 需要用到两个工具:spark窗口函数Window对对象分组 ...

  6. python数据库迁移

    实际操作命令 1,python 文件.py db init 2,python xx.py db migrate -m '版本描述' 3,python xx.py db upgrade 4,python ...

  7. Vue3实现图片滚轮缩放和拖拽

    在项目开发中遇到一个需求: 1:用鼠标滚轮可对图片进行缩放处理 2:点击按钮可对图片进行缩放处理 3:可对图片进行拖拽处理 我在开发中通过自己实现与百度查看优秀的铁子进行了两种类型的使用 <te ...

  8. OpenKruise v1.3:新增自定义 Pod Probe 探针能力与大规模集群性能显著提升

    简介: 在版本 v1.3 中,OpenKruise 提供了新的 CRD 资源 PodProbeMarker,改善了大规模集群的一些性能问题,Advanced DaemonSet 支持镜像预热,以及 C ...

  9. 通过Jenkins构建CI/CD实现全链路灰度

    简介: 本文介绍通过 Jenkins 构建流水线的方式实现全链路灰度功能. 作者:卜比   本文介绍通过 Jenkins 构建流水线的方式实现全链路灰度功能. 在发布过程中,为了整体稳定性,我们总是希 ...

  10. 性能透明提升 50%!SMC + ERDMA 云上超大规模高性能网络协议栈

    简介: 新的协议栈是不是重新发明轮子?一个协议栈能否解决所有问题?适配所有场景? 编者按:当前内核网络协议栈有什么问题?新的协议栈是不是重新发明轮子?一个协议栈能否解决所有问题?适配所有场景?本文整理 ...