在后台管理系统中,我们经常会遇到文件导出的需求。下面,我就简单介绍几种常见的导出方式,方便大家以后遇到这样的需求。在实际情况中,采取相对合理的方式。导出目标文件地址在服务器上已经存在,比如用户上传的图片、素材等http://192.168.1.103:3000/imgs/bg.jpg导出接口根据用户需要动态生成文件,比如导出业务流水表、数据汇总表等http://192.168.1.103:3000/api/export导出方法a.downloadhtml5新增属性文件名由前端指定,前端下发保存指令.缺点:IE不支持,而且,在跨域的时候,即使后台设置了允许跨域的响应头,也无法下载,即必须和当前域一致ajax+a.download文件名由前台指定,前台发送保存命令返回后台将二进制数据转换成blob,然后使用URL.createObjectURL创建指向blob的URL在内存中,然后使用a标签的download属性导出。缺点:IE不支持,blobs有内存限制但是避免单独使用a.download必须和域名一致的问题函数useLinkDownload(url,fileName){constlink=document.createElement("a");link.style.display="无";link.href=网址;link.download=文件名;文档。body.appendChild(链接);链接.点击();document.body.removeChild(link);}$.get('http://192.168.1.103:3000/api/export',{responseType:'blob'}).then(function(res){//创建一个指向内存中blob的URLconstobjectURL=URL.createObjectURL(res.data);useLinkDownload(objectURL,'xx.xlsx')URL.revokeObjectURL(objectURL)})ajax+msSaveBlob文件名由前台指定,前台发出保存命令。ieproprietaryapi缺点:chrome和firefox不支持,blob有内存限制$.get('http://192.168.1.103:3000/api/export',{responseType:'blob'}).then(function(res){navigator.msSaveBlob(res.data,"xx.x??lsx");})content-disposition文件名由后台指定。这样指定的文件名优先级高于a.download。前端可以发送请求(其他的交给后台)。后台响应数据时,按照规范设置content-disposition时,需要注意的是不能和ajax结合使用(使用ajax后会变成二进制流,需要前端对流处理)varurl='http://192.168.1.103:3000/api/export'a标签函数useLink(url){constlink=document.createElement("a");link.style.display="无";link.href=网址;document.body.appendChild(链接);链接.点击();document.body.removeChild(链接);}useLink(url)location.hreffunctionuseLocationDownload(url){window.location.href=url;}useLocationDownload(url)window.openfunctionuseWindowOpenDownload(url){window.open(url);}useWindowOpenDownload(url)表单函数useFormDownload(url){constform=document.createElement("form");表单.action=url;form.method="get";form.style.display="无";document.body.appendChild(表单);表单提交();form.remove();}useFormDownload(url)iframe函数useIframeDownload(url){constiframe=document.createElement("iframe");iframe.src=url;iframe.style.display="无";document.body.appendChild(iframe);document.body.removeChild(iframe);}useIframeDownload(url)有些问题跨域a.download无效,即使后台设置了Access-Control-Allow-Origin,download的值也需要与当前域名,让ngnix转发可以解决https://html.spec.whatwg.org/dev/links.html#downloading-resources大文件ajax的方法需要使用blob,blob是有限制的。比如chrome的上限是2GB,所以需要排除ajax方式。可选方法是a.download和Content-Disposition。这两种方法都没有使用blob,所以没有具体的限制。在使用标签或表单时,为了避免导出时页面闪烁,我们可以使用target而不是_self的值来避免,但是当target为_self时,如果导出请求失败,页面会被覆盖,在有什么办法可以避免这个问题?可选的方式有ajax和iframe,这两种方式都可以避免失败时覆盖当前页面,ajax也可以告诉用户失败的原因保存到本地的方式,但是比如图片,文本文件和pdf,浏览器首先尝试打开它们,这在一般情况下是合理的,但是当我们的目的是保存而不是打开时,这就成了问题。上面列出了几种导出方法及其限制。综合来看,Content-Disposition应该是一个比较通用的方法,兼顾了兼容性,避免了浏览器内存的限制。信息https://github.com/eligrey/FileSaver.js/wiki/Saving-a-remote-file#using-http-header