热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

前端文件下载方式方法总结

目录1、利用form.submit直接向后端提交,后端返回文件流2、利于iframe直接向后端提交,后端返回文件流3、使用windows.open下载文件4、解决“无法根据回调函

目录

  • 1、利用form.submit直接向后端提交,后端返回文件流
  • 2、利于iframe直接向后端提交,后端返回文件流
  • 3、使用windows.open下载文件
  • 4、解决“无法根据回调函数做交互”的问题:ajax提交,后端返回在线文件地址
  • 5、解决“无法根据回调函数做交互”的问题:jquery-download 插件
  • 1、利用Html5的download属性进行下载
  • 2、利用Html5的Blob对象实现对文件流进行下载
    • (1)、 使用原生js发送ajax实现
    • (2)、 使用结合jq发送ajax请求实现,需要引入jquery.binarytransport.js插件,其扩展了jq的ajax的dataType的设置;
  • 3、新兴方案中的综合方案:file-saver
    • (1)、FileSaver.js 功能特点
    • (2)、安装
    • (3)、demo:使用 FileSaver.js下载后端返回的文件流;
  • 4、新兴方案的优缺点:

正文

#传统方法

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

回到顶部

1、利用form.submit直接向后端提交,后端返回文件流

  1)前端代码:

1 var downloadURL = "RestHandle.ashx";2 var testForm = $(""); //定义一个form表单3 testForm.attr('style','display:none'); //设置form表单属性4 testForm.attr('target','');5 testForm.attr('method','post');6 testForm.attr('action',downloadURL);7 8 var nameInput = $(''); //构造formdata9 nameInput.attr('type','hidden');
10 nameInput.attr('name','fileName');
11 nameInput.attr('value','test.txt');
12
13 $('body').append(testForm); //将表单放置在web中
14 testForm.append(nameInput); //将formdata添加到表单上
15 testForm.submit(); //表单提交
16 testForm.remove(); //表单移除

  2)服务端代码,以asp.net为例:

1 public class TestHandler : IHttpHandler2 {3 4 public void ProcessRequest(HttpContext context)5 {6 string fileName = context.Request["FileName"];//客户端传送过来的要下载的文件名7 string filePath = System.Web.HttpContext.Current.Server.MapPath("DownLoad/" + fileName);//路径8 9 FileInfo newFile = new FileInfo(filePath);
10
11 //以字符流的形式下载文件
12 FileStream fs = new FileStream(filePath, FileMode.Open);
13 byte[] bytes = new byte[(int)fs.Length];
14 fs.Read(bytes, 0, bytes.Length);
15 fs.Close();
16 context.Response.ContentType = "application/octet-stream";
17 //通知浏览器下载文件而不是打开
18 context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
19 context.Response.BinaryWrite(bytes);
20 context.Response.Flush();
21 context.Response.End();
22 }
23
24 public bool IsReusable
25 {
26 get
27 {
28 return false;
29 }
30 }
31 }

 3)优缺点:

    优点 :兼容性良好,传统方式,不会出现URL长度限制问题;

    缺点:拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示

2、利于iframe直接向后端提交,后端返回文件流

  1)前端代码:

1 function downFileByIframe(parameters) {
2 var downloadURL = "TestHandler.ashx?FileName=test.txt";
3 var iframe = document.createElement("iframe");
4 iframe.src = downloadURL;
5 iframe.style.display = "none";
6 document.body.appendChild(iframe);
7 }

        2)后端代码:同上

  3)优缺点:

    优点: 兼容性较好

    缺点: *html中会增加多余的iframe元素,增加了维护成本;

           *拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示;

           *URL长度有限制;

3、使用windows.open下载文件

  1)前端代码

1 var downloadURL = "TestHandler.ashx?FileName=test.txt";
2 window.open(downloadURL);

  2)后端代码:同上

  3)优缺点:

    优点:  兼容性良好,代码简洁;

    缺点: *URL长度有限制;

           *拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示;

4、解决“无法根据回调函数做交互”的问题:ajax提交,后端返回在线文件地址

  利用ajax去提交请求,后端会返回一个线上的文件地址,前端可以通过原生的window.open打开这个地址就可以实现下载;

  也可以通过a标签设置href以及download属性,并自动点击实现其下载功能,关于其兼容性问题,可以判断download属性是否存在来弥补。

  1)优缺点:

  优点 :可以拿到其返回时机,可以做交互;

  缺点 :线上产生大量的中间临时文件,可以用设置时限来优化。解决方案:可使用大厂的云存储,从而减少临时文件的产生;

  2)前端代码:

1 $.ajax({2 type: "post",3 url: "TestHandler.ashx",4 data: {'FileName':'test.txt'},5 success: function (res) {6 if (res.Status) {7 // window.open或者a标签下载 8 var isSupportDownload = 'download' in document.createElement('a');9 if (isSupportDownload) {
10 var $a = $("");
11 $a.attr({
12 href: res.url,
13 download: 'filename'
14 }).hide().appendTo($("body"))[0].click();
15 } else {
16 window.open(res.url)
17 }
18 } else {
19 alert(res.Message);
20 }
21 }
22 })

 

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)前端代码:

1 var downloadURL = "TestHandler.ashx";2 $.fileDownload(downloadURL, {3 httpMethod: 'post',4 data: { 'FileName': 'test.txt' },5 prepareCallback: function (url) {6 console.log("文件下载中...");7 // 数据加载动画8 $("body").append('

');9 },
10 abortCallback: function (url) {
11 // 异常终止
12 console.log("文件下载异常!!");
13 $("#Loading").remove();
14 },
15 successCallback: function (url) {
16 console.log("文件下载成功!!");
17 $("#Loading").remove();
18 },
19 failCallback: function (html, url) {
20 console.log("文件下载失败!!");
21 $("#Loading").remove();
22 }
23 });

 

  2)后端代码:

1 public void ProcessRequest(HttpContext context)2 {3 string fileName = context.Request["FileName"];//客户端保存的文件名4 string filePath = System.Web.HttpContext.Current.Server.MapPath("DownLoad/" + fileName);//路径5 6 FileInfo newFile = new FileInfo(filePath);7 8 //以字符流的形式下载文件9 FileStream fs = new FileStream(filePath, FileMode.Open);
10 byte[] bytes = new byte[(int)fs.Length];
11 fs.Read(bytes, 0, bytes.Length);
12 fs.Close();
13
14 context.Response.ContentType = "application/octet-stream";
15 context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
16 context.Response.BinaryWrite(bytes);
17
18 //该COOKIE用于告诉jquery.fileDownload.js文件下载成功
19 context.Response.COOKIEs.Add(new HttpCOOKIE("fileDownload", "true"));
20 context.Response.Flush();
21 context.Response.End();
22 }

注意: 这里的后端代码增加了一个名为“fileDownload”的COOKIE的返回;jquery.download.js插件使用该COOKIE来判断是否下载成功,从而进入成功回调函数(successCallback);

 

#新兴方案

回到顶部

1、利用Html5的download属性进行下载

  1)前端代码

DownloadAttrTest

  2)后端代码:同上

  3)优缺点:

    优点:代码简洁

    缺点:存在浏览器兼容性的问题

   4)参考:

    https://www.zhangxinxu.com/wordpress/2016/04/know-about-html-download-attribute/

2、利用Html5的Blob对象实现对文件流进行下载

(1)、 使用原生js发送ajax实现

  1)前端代码:

1 function downByBlob_1(parameters) {2 var downloadURL = "TestHandler.ashx?FileName=zip.rar";3 let xhr = new XMLHttpRequest()4 let fileName = 'zip.rar' // 文件名称 5 xhr.open('GET', downloadURL, true);6 xhr.responseType = 'arraybuffer';7 //xhr.setRequestHeader('xx', 'xxxxx') // 请求头中添加信息8 xhr.onload = function () {9 if (this.status === 200) {
10 let type = xhr.getResponseHeader('Content-Type')
11
12 let blob = new Blob([this.response], { type: type })
13 if (typeof window.navigator.msSaveBlob !== 'undefined') {
14 /*
15 * IE workaround for "HTML7007: One or more blob URLs were revoked by closing
16 * the blob for which they were created. These URLs will no longer resolve as
17 * the data backing the URL has been freed."
18 */
19 window.navigator.msSaveBlob(blob, fileName);
20 } else {
21 let URL = window.URL || window.webkitURL;
22 let objectUrl = URL.createObjectURL(blob);
23 console.log(objectUrl);
24 //"blob:http://localhost:10614/3e48b856-fca6-4e4c-b780-1c4a7066f42e"
25 if (fileName) {
26 var a = document.createElement('a');
27 // safari doesn't support this yet
28 if (typeof a.download === 'undefined') {
29 window.location = objectUrl
30 } else {
31 a.href = objectUrl;
32 a.download = fileName;
33 document.body.appendChild(a);
34 a.click();
35 a.remove();
36 }
37 } else {
38 window.location = objectUrl;
39 }
40 }
41 }
42 }
43 xhr.send();
44 }

   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)前端代码:

1 function downByBlob_2(parameters) {2 $.ajax({3 type: "post",4 url: "TestHandler.ashx",5 data: { 'FileName': 'zip.rar' },6 dataType: 'binary',7 responseType: 'arraybuffer',8 success: function (msg) {9 let blob = new Blob([msg]);
10
11 console.log("Blob:" + msg); //msg 已不是乱码
12 let url = window.URL.createObjectURL(blob);
13
14 let a = document.createElement("a");
15 document.body.appendChild(a);
16 a.href = url;
17 a.download = 'zip.rar'; //命名下载名称
18 a.click(); //点击触发下载
19 window.URL.revokeObjectURL(url); //下载完成进行释放
20 }
21 });
22 }

        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)前端代码:

1 function downByFileSaver(parameters) {
2 saveAs('TestHandler.ashx?FileName=zip.rar');
3 }

     2)后端代码:同上

回到顶部

4、新兴方案的优缺点:

  优点:技术新颖,某些场景下使用方便;

  缺点:兼容性不好;

5.使用 Javascript API -- fetch 实现文件下载功能


 前端代码:

fetch('https://jsonplaceholder.typicode.com/todos/1').then(resp => resp.blob()).then(blob => {const url = window.URL.createObjectURL(blob);const a = document.createElement('a');a.style.display = 'none';a.href = url;// the filename you wanta.download = 'todo-1.json';document.body.appendChild(a);a.click();window.URL.revokeObjectURL(url);alert('your file has downloaded!'); // or you know, something with better UX...}).catch(() => alert('oh no!'));

  后端代码同上

#参考

  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


推荐阅读
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 本文介绍了如何在 ASP.NET 中设置 Excel 单元格格式为文本,获取多个单元格区域并作为表头,以及进行单元格合并、赋值、格式设置等操作。 ... [详细]
  • LDAP服务器配置与管理
    本文介绍如何通过安装和配置SSSD服务来统一管理用户账户信息,并实现其他系统的登录调用。通过图形化交互界面配置LDAP服务器,确保用户账户信息的集中管理和安全访问。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 自动验证时页面显示问题的解决方法
    在使用自动验证功能时,页面未能正确显示错误信息。通过使用 `dump($info->getError())` 可以帮助诊断和解决问题。 ... [详细]
  • importpymysql#一、直接连接mysql数据库'''coonpymysql.connect(host'192.168.*.*',u ... [详细]
  • CentOS 7 中 iptables 过滤表实例与 NAT 表应用详解
    在 CentOS 7 系统中,iptables 的过滤表和 NAT 表具有重要的应用价值。本文通过具体实例详细介绍了如何配置 iptables 的过滤表,包括编写脚本文件 `/usr/local/sbin/iptables.sh`,并使用 `iptables -F` 清空现有规则。此外,还深入探讨了 NAT 表的配置方法,帮助读者更好地理解和应用这些网络防火墙技术。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 本文深入解析了HTML框架集(FRAMESET)的使用方法及其应用场景。首先介绍了几个关键概念,如如何通过FRAMESET标签将主视图划分为多个独立的区域,每个区域可以加载不同的HTML文件。此外,还详细探讨了FRAMESET在实际开发中的优缺点,并提供了具体的实例代码,帮助开发者更好地理解和应用这一技术。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 本文详细解析了JSONP(JSON with Padding)的跨域机制及其工作原理。JSONP是一种通过动态创建``标签来实现跨域请求的技术,其核心在于利用了浏览器对``标签的宽松同源策略。文章不仅介绍了JSONP的产生背景,还深入探讨了其具体实现过程,包括如何构造请求、服务器端如何响应以及客户端如何处理返回的数据。此外,还分析了JSONP的优势和局限性,帮助读者全面理解这一技术在现代Web开发中的应用。 ... [详细]
  • 利用PaddleSharp模块在C#中实现图像文字识别功能测试
    PaddleSharp 是 PaddleInferenceCAPI 的 C# 封装库,适用于 Windows (x64)、NVIDIA GPU 和 Linux (Ubuntu 20.04) 等平台。本文详细介绍了如何使用 PaddleSharp 在 C# 环境中实现图像文字识别功能,并进行了全面的功能测试,验证了其在多种硬件配置下的稳定性和准确性。 ... [详细]
author-avatar
a734839433
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有