前端通过二进制流下载文件

JS下载文件两种方式总结:
下载文件主要分为两种形式,具体使用哪种方式取决于后台;

1.如果后台服务器的静态目录有可供下载的静态资源,后台接口返回文件路径,直接window.location.href=url或者window.open(url)或者创建a标签并指定a.href=url模拟点击进行下载即可;

2.如果后台服务器无可供下载的静态资源,返回的是一个文件流(response-type: application/octet-stream;charset=UTF-8 ),则使用第二种方式(将文件写入内存,并且创建a元素,a链接href属性指向内存中的文件,download属性指向要下载的文件名,模拟a元素的点击事件进行下载然后移除a元素)。

本文主要说明采用文件流的方式下载文件。

一、后台服务器有静态资源且是固定的文件名(GET方式下载文件)
window.location.href="http://www.域名/template.xlsx(请求返回的url地址)"
二、后台返回文件流
方案1:采用FileReader读取二进制流,下载读取后的结果
                  import axios from 'axios'
                axios.post(this.$globalConf.atapPathPrefix + '/system/indicator/export', postParams, { responseType: 'blob' }).then(res => {
                    let blob = res.data;
                    let reader = new FileReader();
                    reader.readAsDataURL(blob);
                    reader.onload = function(e) {
                        let a = document.createElement('a');
                        let fileName = res.headers["content-disposition"] ? res.headers["content-disposition"].split(';')[1].split('=')[1] : new Date().getTime() + '.xlsx'
                        a.download = decodeURIComponent(fileName)//解码
                        a.href = e.target.result;
                        document.body.appendChild(a);
                        a.click();
                        document.body.removeChild(a);
                      } 
                  })

方案二:通过URL.createObjectURL读取二进制流并返回一个对象URL,原理同上
                  import axios from 'axios'
                  axios.post(this.$globalConf.atapPathPrefix + '/system/indicator/export', postParams, { responseType: 'blob' }).then(res => {
                    //这里res.data是返回的blob对象,即对应的二进制流
                    let blob = res.data
                    let downloadElement = document.createElement('a');
                    let href = window.URL.createObjectURL(blob); //创建下载的链接
                    let fileName = res.headers["content-disposition"] ? res.headers["content-disposition"].split(';')[1].split('=')[1] : new Date().getTime() + '.xlsx'
                    
                    downloadElement.href = href;
                    downloadElement.download = decodeURIComponent(fileName)//解码
                    document.body.appendChild(downloadElement);
                    downloadElement.click();
                    document.body.removeChild(downloadElement);
                    window.URL.revokeObjectURL(href); //释放掉blob对象
                })
可能出现的问题:

无法获取headers的content-disposition字段
本次请求获取到fileName如下:

image.png

解决办法

在服务端设置header

Access-Control-Expose-Headers: Content-Disposition

(3)Access-Control-Expose-Headers
该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

摘自阮一峰-跨域资源共享 CORS 详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 什么是跨域HTTP请求 现代浏览器出于安全的考虑,使用 XMLHttpRequest对象发起 HTTP请求时必须遵...
    孤独的人最善良阅读 1,171评论 0 0
  • 1.同源策略(Same origin Policy) 浏览器出于安全方面的考虑,只允许与本域下的接口交互。不同源的...
    好奇男孩阅读 328评论 0 2
  • CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。 ...
    奇特思维家阅读 1,118评论 0 3
  • 题目1.什么是同源策略? 同源策略(Same origin Policy): 浏览器出于安全方面的考虑,只允许与本...
    FLYSASA阅读 1,708评论 0 6
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139