资讯专栏INFORMATION COLUMN

JS下载文件常用的方式

alaege / 2984人阅读

摘要:下载附件,,,,,,应该是实际工作中经常遇到一个问题这里使用过几种方式分享出来仅供参考初次写可能存在问题有问题望指出主要了解的几个知识点响应头设置这里只需要涉及跨域的时才使用,用于暴露中能够获取到响应头字段先来介绍常用方式这里下载文

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

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

http 响应头设置

Content-Disposition

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

Blob 、 FileReader

URL

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

利用 iframe 或 a 连接 服务端代码
// nodejs
const 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 适用哪些对象?

load

​ W3C 对 load 定义

Type load
Sync / Async Async
Bubbles No
Trusted Targets Window, 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文件内容乱码等;

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100868.html

相关文章

  • NPM — JavaScript 包管理器

    摘要:是的默认模块管理器,一个命令行下的软件,用来安装和管理模块,同时也可以管理其他开放式的模块代码。的包管理器可以查看所有可使用的命令。发布记得在推之前先登录要不然会报错。最后需要把文件里面的删除掉要不然上传时会忽略掉打包的文件。 本文主要介绍npm的常用命令,以及如何发布一些常用的js模块化代码到npm上面方便日后的使用,和举例如何把一个vue组件打包发布到npm到最后下载到本地使用的过...

    ZweiZhao 评论0 收藏0
  • 后端开发者Vue学习之路(四)

    摘要:文件是当前项目的首页文件。以后可能还会有全局注册组件等操作。在上面使用了这是一个预定义的路径,代表目录。而为了使用好这个实例,不要修改的,不然装载完内容后,对应的管理区域会指向不明,而导致渲染失败。目录 上节内容回顾: npm 介绍 安装 常用命令: 补充: ...

    番茄西红柿 评论0 收藏0
  • ES6常用语法到Node浅谈

    摘要:是解释性语言因服务端的应用,而贯通了前后台。关于和声明的变量和声明的变量整体,会被提升到当前作用域的顶部。做后台服务端,处理请求的代码,得自己实现了。为提高下载速度,可通过来切换镜像源。 JS是解释性语言,因node服务端的应用,而贯通了前后台。 【ES6】 关于var和let var: 1.var声明的变量和function声明的变量整体,会被提升到当前作用域的顶部。 2...

    weizx 评论0 收藏0
  • 脚本加载和执行

    摘要:现在对的使用非常普遍,任何一个站点都会请求大量的脚本,而加载和执行的方式也是各不相同,希望读完这篇文章可以对常用的加载和执行方式有一个整体的认识。总结上文主要介绍了动态创建脚本和的方式去创建异步加载和执行脚本的方式。 在打开一个站点的时候,浏览器会去加载各种资源。现在对JS的使用非常普遍,任何一个站点都会请求大量的JS脚本,而加载和执行的方式也是各不相同,希望读完这篇文章可以对常用的加...

    TANKING 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<