vue+axios文件上傳/下載完美解決方案

需求分析: 因為axios在請求時定制了很多個性化需求,比如攜帶token嘲玫,比如指明服務(wù)器域名等等,如果采用相對地址href的請求方式以及部分框架自帶的文件上傳方式征冷,是無法滿足需求的漓帅,我們的目的是采用相同的get和post完成文件下載和上傳工作

下面直接分享解決方案

 //文件上傳, 相對簡單些芬首,返回的都是json數(shù)據(jù)
submitUpload() {
    if(!this.checkUpload()) return false
        let fileFormData = new FormData();
        //this.file 更具不同ui框架獲取的file對象,this.file.raw文件的二進(jìn)制流
        fileFormData.append('file', this.file.raw);
        let requestConfig = {
         //重新設(shè)置請求頭,考慮服務(wù)器處理時間可能過長,加大timeout
            headers: {
                'Content-Type': 'multipart/form-data',
                timeout: 20000,
            },
        }
        this.$axios.post(this.url, fileFormData, requestConfig).then(() => {
            this.$message({
                message: '文件上傳成功',
                type: 'success',
                duration: 1500,
                onClose: () => {
                    //文件上傳已經(jīng)做成了組件.vue,向父類組件發(fā)送done消息,用于更新table等
                    this.$emit('done')
                }
            })
        })
},

//文件下載
//重點:一切正常,返回的是blob數(shù)據(jù),創(chuàng)建一個a標(biāo)簽下載文件
//難點:如果服務(wù)器報,返回的可是一個json數(shù)據(jù),特殊處理提取出來
download(){
    this.$axios.get(this.url, {
        responseType: 'blob', // important
        timeout: 20000,
    }).then((response) => {
        //返回的是一個錯誤
        if(response.headers['content-type']==='application/json'){
            //提取錯誤的json消息并轉(zhuǎn)換(此時json消息依舊在response.data中,這是一個blob數(shù)據(jù))
            let reader = new FileReader();
            reader.onload = e => this.$message.error(JSON.parse(e.target.result).msg);
            reader.readAsText(response.data);
            return false;
        }
        //接收的是文件,fileName是一個property,設(shè)置了默認(rèn)值(比如"文件模版.xls")
        let fileName = this.fileName;
        //服務(wù)器返回的請求頭中包含了文件名信息,提取出來
        //可能出現(xiàn)的BUG:如果在響應(yīng)頭中能看到"content-disposition",axios拿到的response卻沒有,
        //這不怪axios,你需要去服務(wù)器設(shè)置一個叫Access-Control-Expose-Headers的東西
        //讓它包含"content-disposition"
        if(response.headers["content-disposition"]){
            const patt = new RegExp("filename=([^;]+\\.[^\\.;]+);*");
            const result = patt.exec(response.headers["content-disposition"]);
            if(result.length>1){
                //中文解碼
                fileName = decodeURI(result[1]);
            }
        }
        //制作a標(biāo)簽并點擊下載
        const url = window.URL.createObjectURL(new Blob([response.data],
            { type: 'application/octet-stream' }));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', fileName);
        document.body.appendChild(link);
        link.click();
    });

總結(jié): 文件上傳在于獲得文件二進(jìn)制流并制作成FormData進(jìn)行post請求到踏,同時header需設(shè)置Content-Type='multipart/form-data'。
而文件下載則更復(fù)雜些泻红,需從response.data中獲得blob(文件二進(jìn)制流)創(chuàng)建本地的下載標(biāo)簽a夭禽,最后點擊下載,同時還需注意如果發(fā)生錯誤谊路,服務(wù)器返回的是json數(shù)據(jù),該數(shù)據(jù)依舊存在于response.data并以blob形式存在菩彬,需特殊處理提取出來并解析缠劝。
以上,依照不重復(fù)造輪子原則骗灶,可以把這兩類分別做成兩個組件惨恭,合理利用<slot>標(biāo)簽和property屬性做到代碼寫一次,到處可復(fù)用原則耙旦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脱羡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锉罐,老刑警劉巖帆竹,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脓规,居然都是意外死亡栽连,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門侨舆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秒紧,“玉大人,你說我怎么就攤上這事挨下∪刍郑” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵臭笆,是天一觀的道長叙淌。 經(jīng)常有香客問我,道長耗啦,這世上最難降的妖魔是什么凿菩? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮帜讲,結(jié)果婚禮上衅谷,老公的妹妹穿的比我還像新娘。我一直安慰自己似将,他們只是感情好获黔,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著在验,像睡著了一般玷氏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腋舌,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天盏触,我揣著相機(jī)與錄音,去河邊找鬼块饺。 笑死赞辩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的授艰。 我是一名探鬼主播辨嗽,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淮腾!你這毒婦竟也來了糟需?” 一聲冷哼從身側(cè)響起屉佳,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洲押,沒想到半個月后武花,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡诅诱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年髓堪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娘荡。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡干旁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炮沐,到底是詐尸還是另有隱情争群,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布大年,位于F島的核電站换薄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏翔试。R本人自食惡果不足惜轻要,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望垦缅。 院中可真熱鬧冲泥,春花似錦、人聲如沸壁涎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怔球。三九已至嚼酝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竟坛,已是汗流浹背闽巩。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留担汤,地道東北人又官。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像漫试,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碘赖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容