【JS】前端文件下载(无刷新)方法总结
#传统方法
利用iframe 或 form.submit 或 windows.open直接向后端发请求,后端返回文件流,后端处理成功后会直接返回到页面,浏览器会整理并打开自己的保存下载文件机制 。
1、利用form.submit直接向后端提交,后端返回文件流
1)前端代码:
var downloadURL = "RestHandle.ashx";
var testForm = $("<form>"); //定义一个form表单
testForm.attr('style','display:none'); //设置form表单属性
testForm.attr('target','');
testForm.attr('method','post');
testForm.attr('action',downloadURL); var nameInput = $('<input>'); //构造formdata
nameInput.attr('type','hidden');
nameInput.attr('name','fileName');
nameInput.attr('value','test.txt'); $('body').append(testForm); //将表单放置在web中
testForm.append(nameInput); //将formdata添加到表单上
testForm.submit(); //表单提交
testForm.remove(); //表单移除
2)服务端代码,以asp.net为例:
public class TestHandler : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
string fileName = context.Request["FileName"];//客户端传送过来的要下载的文件名
string filePath = System.Web.HttpContext.Current.Server.MapPath("DownLoad/" + fileName);//路径 FileInfo newFile = new FileInfo(filePath); //以字符流的形式下载文件
FileStream fs = new FileStream(filePath, FileMode.Open);
byte[] bytes = new byte[(int)fs.Length];
fs.Read(bytes, , bytes.Length);
fs.Close();
context.Response.ContentType = "application/octet-stream";
//通知浏览器下载文件而不是打开
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
context.Response.BinaryWrite(bytes);
context.Response.Flush();
context.Response.End();
} public bool IsReusable
{
get
{
return false;
}
}
}
3)优缺点:
优点 :兼容性良好,传统方式,不会出现URL长度限制问题;
缺点:拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示
2、利于iframe直接向后端提交,后端返回文件流
1)前端代码:
function downFileByIframe(parameters) {
var downloadURL = "TestHandler.ashx?FileName=test.txt";
var iframe = document.createElement("iframe");
iframe.src = downloadURL;
iframe.style.display = "none";
document.body.appendChild(iframe);
}
2)后端代码:同上
3)优缺点:
优点: 兼容性较好
缺点: *html中会增加多余的iframe元素,增加了维护成本;
*拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示;
*URL长度有限制;
3、使用windows.open下载文件
1)前端代码
var downloadURL = "TestHandler.ashx?FileName=test.txt";
window.open(downloadURL);
2)后端代码:同上
3)优缺点:
优点: 兼容性良好,代码简洁;
缺点: *URL长度有限制;
*拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示;
4、解决“无法根据回调函数做交互”的问题:ajax提交,后端返回在线文件地址
利用ajax去提交请求,后端会返回一个线上的文件地址,前端可以通过原生的window.open打开这个地址就可以实现下载;
也可以通过a标签设置href以及download属性,并自动点击实现其下载功能,关于其兼容性问题,可以判断download属性是否存在来弥补。
1)优缺点:
优点 :可以拿到其返回时机,可以做交互;
缺点 :线上产生大量的中间临时文件,可以用设置时限来优化。解决方案:可使用大厂的云存储,从而减少临时文件的产生;
2)前端代码:
$.ajax({
type: "post",
url: "TestHandler.ashx",
data: {'FileName':'test.txt'},
success: function (res) {
if (res.Status) {
// window.open或者a标签下载
var isSupportDownload = 'download' in document.createElement('a');
if (isSupportDownload) {
var $a = $("<a>");
$a.attr({
href: res.url,
download: 'filename'
}).hide().appendTo($("body"))[0].click();
} else {
window.open(res.url)
}
} else {
alert(res.Message);
}
}
})
5、解决“无法根据回调函数做交互”的问题:jquery-download 插件
jquery.download.js插件github地址:https://github.com/johnculviner/jquery.fileDownload/blob/master/src/Scripts/jquery.fileDownload.js
jquery.download.js插件cdn地址:https://www.bootcdn.cn/jquery.fileDownload/
支持场景 : 与上面的几种方案相比,这个模块提供的方案更加完善,而不是局限于某种方案,相当于将上面的几种方案结合了起来, 使用率很高。在源码中,我们可以看到在这个模块中针对各个浏览器和相应的属性是否支持进行了比较全面的兼容。其对应的下载文件方案包括了以下几种。
- window.open(url)打开某个文件地址
- iframe的框架中,设置src属性,通过iframe进行文件的下载,支持文件地址
- 通过form标签,设置action的文件地址,然后通过form的提交来完成文件的下载
1)前端代码:
var downloadURL = "TestHandler.ashx";
$.fileDownload(downloadURL, {
httpMethod: 'post',
data: { 'FileName': 'test.txt' },
prepareCallback: function (url) {
console.log("文件下载中...");
// 数据加载动画
$("body").append('<div id="Loading" style="background:url(images/load.png) top center no-repeat;"></div>');
},
abortCallback: function (url) {
// 异常终止
console.log("文件下载异常!!");
$("#Loading").remove();
},
successCallback: function (url) {
console.log("文件下载成功!!");
$("#Loading").remove();
},
failCallback: function (html, url) {
console.log("文件下载失败!!");
$("#Loading").remove();
}
});
2)后端代码:
public void ProcessRequest(HttpContext context)
{
string fileName = context.Request["FileName"];//客户端保存的文件名
string filePath = System.Web.HttpContext.Current.Server.MapPath("DownLoad/" + fileName);//路径 FileInfo newFile = new FileInfo(filePath); //以字符流的形式下载文件
FileStream fs = new FileStream(filePath, FileMode.Open);
byte[] bytes = new byte[(int)fs.Length];
fs.Read(bytes, , bytes.Length);
fs.Close(); context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
context.Response.BinaryWrite(bytes); //该cookie用于告诉jquery.fileDownload.js文件下载成功
context.Response.Cookies.Add(new HttpCookie("fileDownload", "true"));
context.Response.Flush();
context.Response.End();
}
注意: 这里的后端代码增加了一个名为“fileDownload”的cookie的返回;jquery.download.js插件使用该cookie来判断是否下载成功,从而进入成功回调函数(successCallback);
#新兴方案
1、利用Html5的download属性进行下载
1)前端代码
<a href="TestHandler.ashx?FileName=test.txt" download="test1.txt">DownloadAttrTest</a>
2)后端代码:同上
3)优缺点:
优点:代码简洁
缺点:存在浏览器兼容性的问题
4)参考:
https://www.zhangxinxu.com/wordpress/2016/04/know-about-html-download-attribute/
2、利用Html5的Blob对象实现对文件流进行下载
(1)、 使用原生js发送ajax实现
1)前端代码:
function downByBlob_1(parameters) {
var downloadURL = "TestHandler.ashx?FileName=zip.rar";
let xhr = new XMLHttpRequest()
let fileName = 'zip.rar' // 文件名称
xhr.open('GET', downloadURL, true);
xhr.responseType = 'arraybuffer';
//xhr.setRequestHeader('xx', 'xxxxx') // 请求头中添加信息
xhr.onload = function () {
if (this.status === 200) {
let type = xhr.getResponseHeader('Content-Type') let blob = new Blob([this.response], { type: type })
if (typeof window.navigator.msSaveBlob !== 'undefined') {
/*
* IE workaround for "HTML7007: One or more blob URLs were revoked by closing
* the blob for which they were created. These URLs will no longer resolve as
* the data backing the URL has been freed."
*/
window.navigator.msSaveBlob(blob, fileName);
} else {
let URL = window.URL || window.webkitURL;
let objectUrl = URL.createObjectURL(blob);
console.log(objectUrl);
//"blob:http://localhost:10614/3e48b856-fca6-4e4c-b780-1c4a7066f42e"
if (fileName) {
var a = document.createElement('a');
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = objectUrl
} else {
a.href = objectUrl;
a.download = fileName;
document.body.appendChild(a);
a.click();
a.remove();
}
} else {
window.location = objectUrl;
}
}
}
}
xhr.send();
}
2)后端代码:同上
(2)、 使用结合jq发送ajax请求实现,需要引入jquery.binarytransport.js插件,其扩展了jq的ajax的dataType的设置;
jquery.binarytransport.js插件github地址:https://github.com/henrya/js-jquery/tree/master/BinaryTransport
注意:当下载的是纯文本文件时,是不需要引入插件,ajax也不用配置dataType,直接用jq的ajax即可;
1)前端代码:
function downByBlob_2(parameters) {
$.ajax({
type: "post",
url: "TestHandler.ashx",
data: { 'FileName': 'zip.rar' },
dataType: 'binary',
responseType: 'arraybuffer',
success: function (msg) {
let blob = new Blob([msg]); console.log("Blob:" + msg); //msg 已不是乱码
let url = window.URL.createObjectURL(blob); let a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
a.download = 'zip.rar'; //命名下载名称
a.click(); //点击触发下载
window.URL.revokeObjectURL(url); //下载完成进行释放
}
});
}
2)后端代码:同上
3)参考:
http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
https://blog.csdn.net/aydongzhiping/article/details/82462473
3、新兴方案中的综合方案:file-saver
(1)、FileSaver.js 功能特点
- FileSaver.js 是一款基于 HTML5 完成文件保存的插件,它可以帮我们直接从网页中导出多种格式文件。
- 同时对于那些本身不支持 HTML5 W3C saveAs() FileSaver 接口的浏览器,FileSaver.js 也提供了支持。
- 使用 FileSaver.js 可以让 Web 应用完美的生成文件,或者保存那些不应该发送到外部服务器的敏感信息。是一种简单易用的浏览器端文件保存方案。
(2)、安装
FileSaver.js github地址:https://github.com/eligrey/FileSaver.js
可直接下载 FileSaver.js 然后在页面中引用;
npm、bower 安装:
npm install file-saver --save
bower install file-saver
(3)、demo:使用 FileSaver.js下载后端返回的文件流;
1)前端代码:
function downByFileSaver(parameters) {
saveAs('TestHandler.ashx?FileName=zip.rar');
}
2)后端代码:同上
4、新兴方案的优缺点:
优点:技术新颖,某些场景下使用方便;
缺点:兼容性不好;
#参考
https://juejin.im/post/5bd5547a6fb9a05cdd2d5109
https://juejin.im/post/5bd1b0aa6fb9a05d2c43f004
https://www.cnblogs.com/yunser/p/7629399.html
https://blog.csdn.net/wt346326775/article/details/83617663
————————————————————————————————————————————————————
【JS】前端文件下载(无刷新)方法总结的更多相关文章
- SpringMVC结合ajaxfileupload.js实现文件无刷新上传
直接看代码吧,注释都在里面 首先是web.xml <?xml version="1.0" encoding="UTF-8"?> <web-ap ...
- js前端读写文件的方法(json、excel)
1.前端读取文件的实现 关键:利用文件上传对话框预览本地文件.利用FileReader读取文件 前端预览本地文件 <input tabindex="-1" id=" ...
- 无刷新分页 jquery.pagination.js
无刷新分页 jquery.pagination.js 采用Jquery无刷新分页插件jquery.pagination.js实现无刷新分页效果 1.插件参数列表 http://www.dtan.so ...
- ajax实现无刷新分页效果
基于jquery.pagination.js实现的无刷新加载分页数据效果. 简介与说明 * 该插件为Ajax分页插件,一次性加载数据,故分页切换时无刷新与延迟.如果数据量较大,加载会比较慢. * 分页 ...
- SpringMVC ajax技术无刷新文件上传下载删除示例
参考 Spring MVC中上传文件实例 SpringMVC结合ajaxfileupload.js实现ajax无刷新文件上传 Spring MVC 文件上传下载 (FileOperateUtil.ja ...
- ASP.NET工作笔记之一:图片上传预览及无刷新上传
转自:http://www.cnblogs.com/sibiyellow/archive/2012/04/27/jqueryformjs.html 最近项目里面涉及到无刷新上传图片的功能,其实也就是上 ...
- js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符
js中对arry数组的各种操作小结 最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...
- js实现无刷新表单提交文件,将ajax请求转换为form请求方法
最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...
- 前台JS(Jquery)调用后台方法 无刷新级联菜单示例
前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 下面是做的一个前台用JQUERY,AJAX调用后台方法做的无刷新级联菜单 http://www.dtan.so CasMenu.aspx页 ...
随机推荐
- 结对编程项目总结 by:陈宏伟&刘益
结对编程项目在欢快的国庆假期中也顺利结束了.从最初拿到结对编程项目的思考,再到一步一步实现,中间经历了一个漫长的过程.在我和队友的多次协商下,最终我们还是选择使用基于python来实现这一次结对编程项 ...
- MyDAL - .QueryListAsync() 使用
索引: 目录索引 一.API 列表 .QueryListAsync() .QueryListAsync<M>() 如: .QueryListAsync<AgentInventoryR ...
- vue 导出xlsx表功能
详细步骤: 1.需要安装三个依赖: npm install -S file-saver xlsx npm install -D script-loader 两个命令行包含三个依赖. 2.项目中src下 ...
- 安装了精简版的windows 的电脑如何修复?参照的程序集没有安装在系统上
我利用网络上的windows 10 纯净版来进行安装windows 10 镜像的时候,发现很多的windows 的服务都是不能用的.比如启动/删除 windows 功能就是不能用的,会出现如下信息: ...
- Jdk 接口类RandomAccess了解
1. 接口说明 Marker interface used by List implementations to indicate that they support fast (generally ...
- WinForm 双向数据绑定
程序目标: 控件的属性值与对象的属性值双向绑定使窗口控件的属性值与对象的属性值保持一致.对窗口控件属性值更改后立即更新对象的属性值,对对象的属性值更改后立即更新窗口控件的属性值. 程序完整代码包:ht ...
- Installing the Ranger Kafka Plug-in
This section describes how to install and enable the Ranger Kafka plug-in. The Ranger Kafka plug-in ...
- [C#6] 8-异常增强
0. 目录 C#6 新增特性目录 1. 在catch和finally块中使用await 在C#5中引入一对关键字await/async,用来支持新的异步编程模型,使的C#的异步编程模型进一步的简化(A ...
- 利用Python爬取网页图片
最近几天,研究了一下一直很好奇的爬虫算法.这里写一下最近几天的点点心得.下面进入正文: 你可能需要的工作环境: Python 3.6官网下载 我们这里以sogou作为爬取的对象. 首先我们进入搜狗图片 ...
- python上下文管理
一.python上下文介绍: python中的上下文,指的就是代码所执行的环境状态,或者运行的场景 python上下文管理器规定了某个对象的使用范围,当进入或者离开了使用范围,会有相应的操作,多用于资 ...