前端下載文件方案

1. a標(biāo)簽

點(diǎn)擊a 標(biāo)簽,可以直接下載其href屬性對(duì)應(yīng)的文件忽你,文件名為download屬性的對(duì)應(yīng)值阶女。
< a href = " /images/logo.png " download = " /images/logo.png " >
可以用js動(dòng)態(tài)生成一個(gè)a標(biāo)簽痘煤,模擬點(diǎn)擊事件進(jìn)行下載
缺點(diǎn):不能獲取成功事件和異常事件

export const useATagDownLoad = (fileName, objectUrl) => {
  const el = document.createElement('a');
  el.download = fileName;
  el.style.display = 'none';
  el.href = objectUrl;
  document.body.appendChild(el);
  el.click();
  document.body.removeChild(el);
};

2. form 表單

利用form表單的submit功能,可以實(shí)現(xiàn)文件的下載
效果 :在 當(dāng)前頁面打開一個(gè)下載彈框瓦胎,實(shí)現(xiàn)文件的下載
缺點(diǎn):不能獲取成功事件和異常事件

export const useFormDownload = (url, params) => {
  // 導(dǎo)出表格
  const form = document.createElement('form');
  form.id = 'form';
  form.name = 'form';
  document.body.appendChild(form);
  for (const obj in params) {
    if (params.hasOwnProperty(obj)) {
      const input = document.createElement('input');
      input.type = 'hidden';
      input.name = obj;
      input.value = params[obj];
      form.appendChild(input);
    }
  }
  form.method = 'GET'; // 請(qǐng)求方式
  form.action = url;
  form.submit();
  document.body.removeChild(form);
};

3. window.open( url)

window.open(url)會(huì)打開一個(gè)新的窗口進(jìn)行下載芬萍,下載成功后會(huì)自動(dòng)關(guān)閉新窗口,通過監(jiān)聽新窗口的breforeunload事件搔啊,可以知道下載成功了
缺點(diǎn):不能獲取異常事件

 const net = await window.open(url);
 net.addEventListener('beforeunload', (e) => {
   // 下載成功了
   this.appraisalDownLoading = false;
 });
  

4. ajax + window.URL. createObjectURL + a標(biāo)簽

ajax請(qǐng)求拿到文件數(shù)據(jù)后柬祠,利用 window.URL.createObjectURL 創(chuàng)建文件的url,利用a標(biāo)簽下載這個(gè)url.
優(yōu)點(diǎn):可以知道下載成功负芋,可以catch異常
需要注意的是:我們是用http響應(yīng)頭的Content-Disposition:attachment; filename 中的finename當(dāng)做文件名,后端一般是用utf-8編碼漫蛔,而Http 消息只能是 ASCII 編碼,所以文件名可能會(huì)出現(xiàn)亂碼情況,需要后端返回 urlencode 后的finename
參考博客:https://www.cnblogs.com/saryli/p/5455362.html

import axios from 'axios';
import FileType from 'file-type';
export const downloadFile = (path, params) => {
  return axios.get(`${path}`, {
    params,
    responseType: 'arraybuffer',
  });
};

export const downloadToObjectUrl = (() => {
  return async (path, params) => {
    try {
      const res = await downloadFile(path, params);
      const { headers } = res;
      // 失敗時(shí)返回的json
      if (headers && headers['content-type'].includes('json')) {
        throw new Error('fail');
      }
      const buffer = res.data;
      const result = await FileType.fromBuffer(buffer);
      const blob = new Blob([buffer], {
        type: result && result.mime,
      });
      const objectUrl = window.URL.createObjectURL(blob);
      const fileNameMatch = (res.headers['content-disposition'] || '').match(
        /filename="(.*)"/
      );
      return {
        fileHash: params.fileHash,
        fileName: fileNameMatch ? decodeURIComponent(fileNameMatch[1]) : '', // include suffix
        objectUrl,
      };
    } catch (e) {
      throw e;
    }
  };
})();

export const useFormDownload = (url, params) => {
  // 導(dǎo)出表格
  const form = document.createElement('form');
  form.id = 'form';
  form.name = 'form';
  document.body.appendChild(form);
  for (const obj in params) {
    if (params.hasOwnProperty(obj)) {
      const input = document.createElement('input');
      input.type = 'hidden';
      input.name = obj;
      input.value = params[obj];
      form.appendChild(input);
    }
  }
  form.method = 'GET'; // 請(qǐng)求方式
  form.action = url;
  form.submit();
  document.body.removeChild(form);
};

const { fileName, objectUrl } = await downloadToObjectUrl(url, params);
useATagDownLoad(fileName, objectUrl);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旧蛾,一起剝皮案震驚了整個(gè)濱河市莽龟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锨天,老刑警劉巖毯盈,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異病袄,居然都是意外死亡奶镶,警方通過查閱死者的電腦和手機(jī)迟赃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門陪拘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厂镇,“玉大人,你說我怎么就攤上這事左刽∞嘈牛” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵欠痴,是天一觀的道長(zhǎng)迄靠。 經(jīng)常有香客問我,道長(zhǎng)喇辽,這世上最難降的妖魔是什么掌挚? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮菩咨,結(jié)果婚禮上吠式,老公的妹妹穿的比我還像新娘。我一直安慰自己抽米,他們只是感情好特占,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著云茸,像睡著了一般是目。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上标捺,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天懊纳,我揣著相機(jī)與錄音,去河邊找鬼亡容。 笑死嗤疯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的萍倡。 我是一名探鬼主播身弊,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼列敲!你這毒婦竟也來了阱佛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤戴而,失蹤者是張志新(化名)和其女友劉穎凑术,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體所意,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淮逊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年催首,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泄鹏。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡郎任,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出备籽,到底是詐尸還是另有隱情舶治,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布车猬,位于F島的核電站霉猛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏珠闰。R本人自食惡果不足惜惜浅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伏嗜。 院中可真熱鬧坛悉,春花似錦、人聲如沸阅仔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽八酒。三九已至空民,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間羞迷,已是汗流浹背界轩。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衔瓮,地道東北人浊猾。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像热鞍,于是被迫代替她去往敵國(guó)和親葫慎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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