#传统方法

利用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】前端文件下载(无刷新)方法总结的更多相关文章

  1. SpringMVC结合ajaxfileupload.js实现文件无刷新上传

    直接看代码吧,注释都在里面 首先是web.xml <?xml version="1.0" encoding="UTF-8"?> <web-ap ...

  2. js前端读写文件的方法(json、excel)

    1.前端读取文件的实现 关键:利用文件上传对话框预览本地文件.利用FileReader读取文件 前端预览本地文件 <input tabindex="-1" id=" ...

  3. 无刷新分页 jquery.pagination.js

     无刷新分页 jquery.pagination.js 采用Jquery无刷新分页插件jquery.pagination.js实现无刷新分页效果 1.插件参数列表 http://www.dtan.so ...

  4. ajax实现无刷新分页效果

    基于jquery.pagination.js实现的无刷新加载分页数据效果. 简介与说明 * 该插件为Ajax分页插件,一次性加载数据,故分页切换时无刷新与延迟.如果数据量较大,加载会比较慢. * 分页 ...

  5. SpringMVC ajax技术无刷新文件上传下载删除示例

    参考 Spring MVC中上传文件实例 SpringMVC结合ajaxfileupload.js实现ajax无刷新文件上传 Spring MVC 文件上传下载 (FileOperateUtil.ja ...

  6. ASP.NET工作笔记之一:图片上传预览及无刷新上传

    转自:http://www.cnblogs.com/sibiyellow/archive/2012/04/27/jqueryformjs.html 最近项目里面涉及到无刷新上传图片的功能,其实也就是上 ...

  7. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  8. js实现无刷新表单提交文件,将ajax请求转换为form请求方法

    最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...

  9. 前台JS(Jquery)调用后台方法 无刷新级联菜单示例

    前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 下面是做的一个前台用JQUERY,AJAX调用后台方法做的无刷新级联菜单 http://www.dtan.so CasMenu.aspx页 ...

随机推荐

  1. OpenGL Windows 窗口程序环境搭建

    OpenGL环境搭建步骤: Downloading OpenGL 根据官网的说法: In all three major desktop platforms (Linux, macOS, and Wi ...

  2. July 11th, 2018. Wednesday, Week 28th.

    It is during our darkest moments that we must focus to see the light. 越是在艰难的时候就越要着眼于光明. From Aristol ...

  3. Azure按订阅,资源组,资源类型导出所有资源powershell命令

    一般可以借助powershell命令来读取资源:例如:1, 读取某个订阅下的资源:$subscriptionID = "xxxxxxxx"Set-AzureRmContext $s ...

  4. py文件2种执行方式

    import m1# print('模块导入执行', m1.num) # import sys# print(sys.path)import json# print(json) if __name__ ...

  5. 元素定位之Ui-Automator-Viewer的使用

    下载uiautomatorviewer升级版 1. 将所有jar包拷贝到%SDK%/tools\lib目录下,覆盖原来的uiautomatorviewer.jar2. 使用%SDK%/tools\ui ...

  6. ztree 为节点添加点击触发事件

    <SCRIPT type="text/javascript"> var setting = { data : { key : { title : "code& ...

  7. 随心测试_软测基础_007<软测学习路线建议>

    如果你对软测感兴趣,那么如何学习软件测试呢? 贴心小提示:以下内容,仅供参考,不挖坑 1:学习方式_职业教育选择观 ————SX的观点:成本 | 收益说,理性接受 软测产业服务链中,测试工程师重在于& ...

  8. mondb 常用命令学习记录

    mondb 常用命令学习记录 一.MongoDB 下载安装 MongoDB官网 提供了可用于 32 位和 64 位系统的预编译二进制包,你可以从MongoDB官网下载安装,MongoDB 预编译二进制 ...

  9. idea标注yml资源配置文件

  10. stm32矩阵键盘扫描数据通过USB发送

                   Keyboard.c #include "keyboard.h"#include "my_usb.h"#include " ...