在web开发中,如果想让用户下载或导出一个文件,应该怎么办?传统的方式是在后台存储或生成一个文件来提供下载功能。这样做的优点是可以做权限控制和二次数据处理,缺点是需要额外发起请求,增加服务器压力,下载速度变慢。但是随着HTML5标准的发布,我们已经只能在前端下载各种文件了。BackendResponsiveDownload在常规的HTTP响应中,Content-Disposition消息头指示响应的内容应该以什么形式显示,是内联的(即网页还是页面的一部分),还是下载并保存作为本地的附件。在HTTP场景下,第一个参数要么是inline(默认值,表示回复中的消息体会显示为页面的一部分,要么是整个页面),或者attachment(意思是消息体要下载到本地;大多数浏览器会出现一个“另存为”对话框,预填文件名的值作为下载的文件名)。只要我们在后端响应头中设置头信息,就可以以文件的形式下载,而不是请求显示:Content-Type:text/html;charset=utf-8Content-Disposition:附件;filename="cool.html"但需要注意的是,如果要通过这种方式下载文件,不能使用AJAX,需要新建一个标签来模拟点击下载。原因是出于安全考虑,JavaScript无法与磁盘进行交互,因此AJAX获取的内容将保存在内存中,而不是磁盘中。Nginx添加header下载位置~\.(jpg|jpeg|png|bmp|ico|gif|swf)${add_headerContent-Disposition'attachment;filename="cool.html"';}和后台一样的原理,只是通过Nginx统一添加header信息。前端下载:标签的download属性该属性指示浏览器下载该URL而不是导航到该URL,因此会提示用户将其保存为本地文件。如果该属性有一个值,那么它将被用作下载的文件名。该属性的允许值没有限制,但是/和\被转换为下划线。此属性仅适用于同源URL。尽管HTTPURL需要来自同一来源,但blob:URL和data:URL可用于促进用户下载JavaScript生成的内容(例如使用在线绘图Web应用程序创建的照片)。常规的标签用于链接跳转,比如新页面,所以如果我们在标签中加入download属性,用户可以很方便的保存新的html页面。PHP实现并发请求生成并下载字符串文件首先我们要了解一种特殊的数据格式:斑点。Blob数据Blob(BinaryLargeObject,二进制类型的大对象),表示一个不可变原始数据的类文件对象。我们上传文件时常用的File对象继承自Blob,并扩展支持用户系统。文档。我们只能通过Blob()构造函数来创建一个新的Blob对象:Blob(blobParts[,options])//创建一个json类型的Blob对象,支持传入同类型数据的数组vardebug={hello:"world"};varblob=newBlob([JSON.stringify(debug,null,2)],{type:'application/json'});//此时blob的值//Blob(22){size:22,type:'application/json'}Blob对象有两个只读属性:size:Blob对象中包含的数据的大小(以字节为单位)。type:一个字符串,指示Blob对象中包含的数据的MIME类型。如果类型未知,则值为空字符串。URL对象和下载字符串文件URL接口是一个用于创建URL的对象,它包含两个静态方法:objectURL=URL.createObjectURL(blob)创建一个包含唯一blob链接(链接协议以blob:,后跟一个在浏览器中唯一标识对象的掩码)。此URL的生命周期与创建它的窗口中的文档相关联。URL.revokeObjectURL(objectURL)销毁之前使用URL.createObjectURL()方法创建的URL实例。浏览器会在文档退出时自动释放它们,但为了获得最佳性能和内存使用,您应该在安全时主动释放它们。varurl=URL.createObjectURL(blob);//此时url的值绑定了文档,所以每个页面创建的字符串都不一样//blob:https://developer.mozilla.org/defe53c2-2882-43c6-b275-db2a57959789此时我们在页面新建一个标签,点击下载我们想要的文件:下载文件链接FileReader读取Blob数据读取Blob数据的唯一方法是FileReader。FileReader对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用File或Blob对象指定要读取的文件或数据。File对象可以是用户在元素上选择文件后返回的FileList对象,也可以是拖拽操作生成的DataTransfer对象,也可以是HTMLCanvasElement执行mozGetAsFile()方法后返回的结果.该对象包含3个属性:FileReader.error指示读取文件时发生错误的DOMException。FileReader.readyState代表FileReader状态的数字。取值如下:常量名称值说明EMPTY0还没有加载数据。LOADING1正在加载数据。DONE2所有读取请求已完成。FileReader.result文件内容。此属性仅在读取操作完成后才有效,数据的格式取决于使用哪种方法启动读取操作。包含6个事件处理:onabort、onerror、onload、onloadstart、onloadend、onprogress,这些就不详细说了,因为FileReader继承自EventTarget,所以这些事件也都可以通过addEventListener方法使用。包含5个方法:FileReader.abort()中止读取操作。返回时,readyState属性为DONE。FileReader.readAsArrayBuffer()开始读取指定Blob中的内容。一旦完成,result属性将保存读取文件的ArrayBuffer数据对象。FileReader.readAsBinaryString()开始读取指定Blob中的内容。完成后,结果属性将包含读取文件的原始二进制数据。FileReader.readAsDataURL()开始读取指定Blob中的内容。完成后,result属性将包含一个data:URL格式字符串,表示读取文件的内容。FileReader.readAsText()开始读取指定Blob中的内容。完成后,result属性将包含一个表示读取的文件内容的字符串。所以我们可以直接读取Blob对象的数据:varreader=newFileReader();reader.addEventListener("loadend",function(){console.log(reader.result);});reader.readAsDataURL(blob);//此时result的值//data:application/json;base64,ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ==reader.readAsText(blob);//此时result的值//{//"hello":"world"//}下载除了下载手动生成的图片字符串或对象外,我们还可以提供下载图片的功能。一方面可以用来支持Canvas画图的保存功能,另一方面可以提供批量下载图片等高级功能。除了浏览器自带的右键保存,我们还可以这样下载图片://通过src获取图片的blob对象functiongetImageBlob(url,cb){varxhr=newXMLHttpRequest();xhr.open("get",url,true);xhr.responseType="blob";xhr.onload=function(){if(this.status==200){cb(this.response);}};xhr.send();}letreader=newFileReader();reader.addEventListener("loadend",function(){console.log(reader.result);});getImageBlob('https://cdn.segmentfault.com/v-5c4ec07f/global/img/user-64.png',function(blob){//读取并查看下载的内容reader.readAsDataURL(blob);//最终生成的字符串//data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAA...//生成一个用于下载的URL对象leturl=URL.createObjectURL(blob);//生成一个a标签,模拟点击下载,类似批量下载letaDom=aDom=document.createElement('a');aDom.href=url;aDom.download='download.json';aDom.text='下载文件';document.getElementsByTagName('body')[0].appendChild(aDom);aDom。点击();});下载excel文件等,如果你了解下载的原理,那么所有的内容都可以理解解决方法,转换成相应的格式即可。当然,你不需要配置复杂格式的文档,导入第三方库也可以。excel文档方面,我选择使用tableExportlibrary://ImportCDNfiles'https://cdn.bootcss.com/xlsx/0.14.1/xlsx.core.min.js','https://cdn.bootcss.com/FileSaver.js/2014-11-29/FileSaver.min.js','https://cdn.bootcss.com/TableExport/5.2.0/js/tableexport.min.js'//绑定下载事件,这是我自己场景下的代码,不一定适合所有人,具体参考官网文档consttableDom=$('#table');$('.table-exportBtn',tableDom).on('click',function(){consttableExport=tableDom.tableExport({formats:['xlsx','txt'],filename:'tabledownload',exportButtons:false});consttype=$(this).data().type;constexportData=tableExport.getExportData()[tableDom[0].id][type];const{data,mimeType,filename,fileExtension,merges,RTL,sheetname}=exportData;//完整的参数只能在源码中看到,官方文档没有写完整,导致下载的文件格式不对默认方法会自动生成下载按钮,但是如果想自定义下载功能,参考exportButtons:false设置部分,但是这个文档有问题,export2file参数不全,导致downloadedxlsx文件的格式一直是错误的。通过查看源码,需要把所有的参数都写上。在上面的例子中,已经写了在tableExport库的源码中,我们可以查看tableExport导出文件的核心代码。导出为ex??cel格式比较复杂,由xlsx.core.min.js完成:/***导出并下载文件*@memberofTableExport.prototype*@paramdata{String}*@parammime{String}mime类型*@paramname{String}文件名*@paramextension{String}文件扩展名*@parammerges{Object[]}*@paramRTL{Boolean}*/export2file:function(data,mime,name,extension,merges,RTL,sheetname){varformat=extension.slice(1);data=this.getRawData(data,extension,name,merges,RTL,sheetname);if(_isMobile&&(format===_FORMAT.CSV||format===_FORMAT.TXT)){//以指定格式拼凑数据:typeURIvardataURI="data:"+mime+";"+this.charset+","+数据;this.downloadDataURI(dataURI,name,extension);}else{//TODO:`saveAs`不可用时的错误和回退saveAs(newBlob([data],{type:mime+";"+this.charset}),name+exten锡安,真实);}},//先创建标签,然后提供href和download属性,模拟点击downloadDataURI:function(dataURI,name,extension){varencodedUri=encodeURI(dataURI);varlink=document.createElement("a");link.setAttribute("href",encodedUri);link.setAttribute("下载",名称+扩展名);document.body.appendChild(链接);链接.点击();},xlsx文件的导出和导出没仔细研究过。有兴趣的可以查看js-xlsxGithub项目的第三方库。上面我们主要讲了下载背后的原理。可以自己打包,也可以使用现成的第三方库,比如download.js,可以提供大部分常用数据的下载;但如果要下载excel格式的表格数据,推荐使用tableExport.js及其依赖组件参考资料MDN-a:https://developer.mozilla.org...MDN-blob:https://developer.mozilla.org...掘金-WebAPI中Blob详解:https://juejin.im/post/59e35d...MDN-URL:https://developer.mozilla.org...MDN-FileReader:https://developer.mozilla.org...BlogGarden-js获取图片的bloburl值和预览:https://www.cnblogs.com/tujia...tableExport文档:https://tableexport.v5.travis...感谢@Oliveryyoung其他解决方案MDN-Content-Disposition:https://developer.mozilla.org...Ajax请求无法下载文件:https://blog.csdn.net/w405722...Github-download.js:https://github.com/rndme/down..。