3種前端文件下載的方式

前端下載有兩類拓提,一類是直接讓瀏覽器接管的(點(diǎn)擊a鏈接觸發(fā)),另一類是先在內(nèi)存里下載好(blob)框喳,然后調(diào)用瀏覽器的保存坎弯。

1.window.open

我最初使用的方法就是這個(gè)酒朵,只要提供了文件的服務(wù)器地址桦锄,使用window.open也就是在新窗口打開,這時(shí)瀏覽器會(huì)自動(dòng)執(zhí)行下載蔫耽。

2.a標(biāo)簽

其實(shí)window.open和a標(biāo)簽是一樣的结耀,只是a標(biāo)簽是要用戶點(diǎn)擊觸發(fā),而window.open可以主動(dòng)觸發(fā)

后端如果設(shè)置了Content-Disposition 匙铡,那么不需要download屬性也能下載图甜。而且后端還可以設(shè)置文件名。

<a href="https:xxx.mp4" download="test">下載文件</a>

3.xhr(axios)下載

這個(gè)時(shí)候鳖眼,請(qǐng)求發(fā)送的時(shí)候需要注明responseType = "blob",如果沒有設(shè)置的情況下黑毅,new Blob的時(shí)候需要傳入第二個(gè)參數(shù)。比如new Blob([res], { type: xhr.getResponseHeader("Content-Type") });

只是這時(shí)后端就沒法通過body報(bào)錯(cuò)了钦讳。只能通過狀態(tài)碼和響應(yīng)頭來傳遞信息了矿瘦。

最后我還是選擇用json來傳遞信息,設(shè)置這個(gè)responseType: 'blob',以后,返回值會(huì)被轉(zhuǎn)為blob愿卒,這時(shí)我們log可以看到type缚去,是application/json的情況就是報(bào)錯(cuò)的情形。然后我們轉(zhuǎn)化一遍json可以拿到報(bào)錯(cuò)信息琼开,其實(shí)也可以把這個(gè)邏輯加到axios攔截器里面

export const DOWNLOAD_ITEM = async (data: FileItem): Promise<any> => {
  const res: Blob = await request.post(`${PROXY_SUFFIX}/downloadItem`, data, {
    responseType: 'blob',
  })
  // json的情況說明是報(bào)錯(cuò)
  if (res.type !== 'application/json') {
    downloadFile(res, data.name)
  } else {
    const r = await res.text()
    message.error(JSON.parse(r)?.msg)
  }
}

這邊我后端用的是golang的gin框架

返回文件流調(diào)用c.File,文件類型不用傳易结,c.Header("Content-Disposition", "attachment; filename="+req.Name)這個(gè)設(shè)置可以返回文件名。

func (f *FileListAPI) DownloadItem(c *gin.Context) {
    var req response.FileInfo
    err := c.ShouldBindJSON(&req)
    if err != nil {
        response.FailWithMessage(err.Error(), c)
        return
    }
    if req.Path == "" {
        response.FailWithMessage("路徑不能為空", c)
        return
    }
    if req.IsFolder {
        response.FailWithMessage("路徑不能為文件夾", c)
        return
    } else {
        c.Header("Content-Disposition", "attachment; filename="+req.Name)
        // c.Header("Content-Transfer-Encoding", "binary")
        // c.Header("Content-Type", "application/octet-stream")
        c.File(req.Path)
    }
    fmt.Println("req", req)

}

下面是blob對(duì)象下載的邏輯,使用createObjectURL轉(zhuǎn)換為url,然后綁到a鏈接上搞动,通過點(diǎn)擊a鏈接的方式觸發(fā)下載躏精。

/**
 * 使用bolb方式下載
 * @param res
 * @param filename
 * @returns
 */
export function downloadFile(res: Blob, filename: string) {
  const url = window.URL.createObjectURL(new Blob([res]))
  const a = document.createElement('a')
  a.style.display = 'none'
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  window.URL.revokeObjectURL(url) // 釋放blob對(duì)象
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市滋尉,隨后出現(xiàn)的幾起案子玉控,更是在濱河造成了極大的恐慌,老刑警劉巖狮惜,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件高诺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡碾篡,警方通過查閱死者的電腦和手機(jī)虱而,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來开泽,“玉大人牡拇,你說我怎么就攤上這事∧侣桑” “怎么了惠呼?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)峦耘。 經(jīng)常有香客問我剔蹋,道長(zhǎng),這世上最難降的妖魔是什么辅髓? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任泣崩,我火速辦了婚禮,結(jié)果婚禮上洛口,老公的妹妹穿的比我還像新娘矫付。我一直安慰自己,他們只是感情好第焰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布买优。 她就那樣靜靜地躺著,像睡著了一般挺举。 火紅的嫁衣襯著肌膚如雪杀赢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天豹悬,我揣著相機(jī)與錄音葵陵,去河邊找鬼。 笑死瞻佛,一個(gè)胖子當(dāng)著我的面吹牛脱篙,可吹牛的內(nèi)容都是我干的娇钱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绊困,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼文搂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起秤朗,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤煤蹭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后取视,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硝皂,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年作谭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稽物。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡折欠,死狀恐怖贝或,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锐秦,我是刑警寧澤咪奖,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站酱床,受9級(jí)特大地震影響羊赵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜斤葱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一慷垮、第九天 我趴在偏房一處隱蔽的房頂上張望揖闸。 院中可真熱鬧揍堕,春花似錦、人聲如沸汤纸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贮泞。三九已至楞慈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啃擦,已是汗流浹背囊蓝。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留令蛉,地道東北人聚霜。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓狡恬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蝎宇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弟劲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

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