博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS下载文件常用的方式
阅读量:6257 次
发布时间:2019-06-22

本文共 2934 字,大约阅读时间需要 9 分钟。

下载附件(image,doc,docx, excel,zip,pdf),应该是实际工作中经常遇到一个问题;这里使用过几种方式分享出来仅供参考; 初次写可能存在问题,有问题望指出

​ 主要了解的几个知识点:

  • http 响应头设置

    • 这里只需要涉及跨域的时才使用,用于暴露JavaScript中能够获取到响应头字段

先来介绍常用方式: 这里下载.doc文档为例,其它都类似

利用 iframe 或 a 连接

服务端代码

// nodejsconst http = require('http');const fs = require('fs');const path = require('path');http.createServer(function (req, res) {     let filename = encodeURIComponent('微信多开的步骤.doc');    // 下面两个主要在跨域情况下,需要设置的    res.setHeader('Access-Control-Allow-Origin', '*');     res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');        // 设置响应头    res.setHeader('Content-Type', 'application/zip;charset=UTF-8');    res.setHeader('Content-Disposition', `attachment; filename=${filename}`);    let fs.readFile(path.resolve(__dirname, `./微信多开的步骤.doc`), function (err, data) {      if (err) throw err;      res.end(data);});}).listen(3000);

Content-Disposition 消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

​ 大概流程:

​ 1 下载时浏览器会尝试去找下响应头中 Content-Disposition
​ 2 如果不存在,首先尝试去预览方式打开该文件 ,如果能就直接显示否则以附件的形式下载并保存;

注意:指定在下载文件名中文情况下,必须先进行编码;

JS

// iframe var downloadFileUrl = "http://localhost:3000"var elemIF = document.createElement("iframe");elemIF.src = downloadFileUrl;elemIF.style.display = "none";document.body.appendChild(elemIF);// a var a = document.createElement('a');a.href = downloadFileUrl;a.click();

上述两种方式仅仅就是发送一个请求,主要依赖后端的支持;对不需要精确知道文件下载的状态,上面方式就能满足下载;

大家可能有疑问,iframe 不是可以通过 onload 来捕获加载的完成状态 ?

先来看看 load 适用哪些对象?

​ W3C 对 load 定义

Type load
Sync / Async Async
Bubbles No
Trusted Targets , Document, Element

适用对象:window,Document,Element 那么对于我们下载的文件并在其范围;

如果需要捕获文件下载的进度以及文件下载完成的状态,需要使用下面的方式;

XMLHttpRequest

var xhr = new XMLHttpRequest();xhr.open('GET', url);xhr.onprogress = function (event) {    console.log(Math.round(event.loaded / event.total * 100) + "%");};xhr.responseType = 'arraybuffer';xhr.addEventListener('readystatechange', function (event) {    if (xhr.status === 200 && xhr.readyState === 4) {        // 获取响应头主要获取附件名称        var contentDisposition = xhr.getResponseHeader('content-disposition');        // 获取类型类型和编码          var contentType = xhr.getResponseHeader('content-type');        // 构造blob对象,具体看头部提供的链接地址        var blob = new Blob([xhr.response], {            type: contentType        });        var url = window.URL.createObjectURL(blob);        // 获取文件夹名        var regex = /filename=[^;]*/;        var matchs = contentDisposition.match(regex);        if (matchs) {            filename = decodeURIComponent(matchs[0].split("=")[1]);        } else {            filename = +Date.now() + ".doc";        }        var a = document.createElement('a');        a.href = url;        a.download = filename;        a.click();        window.URL.revokeObjectURL(url);        // dosomething    }})xhr.send();

上述对比第一种方式,通过 onprogress 捕获下载进度(界面通过显示进度条来提升体验);通过 readystatechange 监听下载完后并可以做其它的事情;

注意: 必须指定 responseType 类型,可以是arraybuffer 或 blob 否则会出现错误问题 比如 zip,pdf文件下载之后打不开提示错误的格式; .doc,.excel文件内容乱码等;

转载地址:http://yaxsa.baihongyu.com/

你可能感兴趣的文章
喵哈哈村的魔法考试 Round #3 (Div.2) 题解
查看>>
音频 API 一览
查看>>
hive的select重命名字段显示成中文
查看>>
JVM类加载机制与对象的生命周期
查看>>
zabbix主动被动模式说明/区别
查看>>
神奇的AC
查看>>
数据库防火墙——实现数据库的访问行为控制、危险操作阻断、可疑行为审计...
查看>>
PCIE_DMA实例一:xapp1052详细使用说明
查看>>
MySQL也有潜规则 – Select 语句不加 Order By 如何排序?
查看>>
Struts(二十八):自定义拦截器
查看>>
安装Jenkins getting started卡住
查看>>
金软PDF转换(x-PDFConper)
查看>>
喵哈哈村的魔法考试 Round #15 (Div.2) 题解
查看>>
使用架构(XSD)验证XML文件
查看>>
Android开发之httpclient文件上传实现
查看>>
极客头条使用心得
查看>>
CSS解决无空格太长的字母,数字不会自己主动换行的问题
查看>>
日志打印longging模块(控制台和文件同时输出)
查看>>
这些年我们一起搞过的持续集成~Jenkins+Perl and Shell script
查看>>
php新版本号废弃 preg_replace /e 修饰符
查看>>