下载附件(image、doc、docx、excel、zip、pdf)应该是实际工作中经常遇到的问题;下面分享几种常用的方法,仅供参考;初步写的可能有问题,如有问题请指出了解的主要知识点:HTTP响应头设置Content-DispositionAccess-Control-Expose-Headers这个只在涉及到跨域的时候用到,它用于暴露JavaScript中可以获取的响应头字段Blob和FileReaderURL。首先介绍一下常用的方法:这里以下载.doc文档为例,其他类似使用iframe或者a连接服务器代码//nodejsconsthttp=require('http');constfs=require('fs');constpath=require('path');http.createServer(function(req,res){letfilename=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}`);letfs.readFile(path.resolve(__dirname,`./WeChatAdditionalsteps.doc`),function(err,data){if(err)throwerr;res.end(data);});}).listen(3000);Content-Disposition消息头表示回复内容应该以什么形式显示,是内联形式(即网页还是页面的一部分),还是下载后以附件形式保存到本地。大致过程:1下载时,浏览器会尝试在响应标头中找到Content-Disposition;2如果不存在,先尝试以预览模式打开文件,如果可以,则直接显示,否则下载并保存为附件;注:如果下载文件名指定中文,它必须先编码;JS//iframevardownloadFileUrl="http://localhost:3000"varelemIF=document.createElement("iframe");elemIF.src=downloadFileUrl;elemIF.style.display="none";document.body.appendChild(elemIF);//avara=document.createElement('a');a.href=downloadFileUrl;a.click();上面两个第一个方法只是发送请求,主要是依赖的支持后端;如果不需要准确知道文件下载状态,以上方法可以满足下载;你可能会有疑惑,iframe能不能通过onload来捕获加载完成状态?我们来看看load适用于哪些对象?loadW3C定义了TypeloadSync/AsyncAsyncBubblesNoTrustedTargetsWindow,Document,Element用于加载适用对象:window,Document,ElementThen用于我们下载的文件及其范围内;如果需要抓取文件下载的进度和文件下载完成的状态需要使用下面的方法;XMLHttpRequestvarxhr=newXMLHttpRequest();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){//获取响应头主要是获取附件名称varcontentDisposition=xhr.getResponseHeader('content-disposition');//获取类型和编码varcontentType=xhr.getResponseHeader('content-type');//构造一个blob对象,看header提供的链接地址varblob=newBlob([xhr.response],{type:contentType});varurl=window.URL.createObjectURL(blob);//获取文件夹名称varregex=/filename=[^;]*/;varmatches=contentDisposition.match(正则表达式);varfilename=''if(matches){filename=decodeURIComponent(matchs[0].split("=")[1]);}else{filename=+Date.now()+".doc";}vara=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文件内容乱码等;
