欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS二進制流文件下載導出(接口返回二進制流)亂碼處理方法

 更新時間:2023年12月20日 11:20:37   作者:hzxOnlineOk  
這篇文章主要介紹了JS二進制流文件下載導出(接口返回二進制流)亂碼處理方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧

給下載文件起名字有兩種方式:

  • 固定值+時間戳(一般都加上時間戳)
  • 后端將文件名放到response的headers中返回,我們?nèi)≈诞斪鑫募?/li>

 使用react的同學注意了,fetch難設(shè)置亂碼轉(zhuǎn)碼,建議使用axios,用fetch親自嘗試失敗+10086次,下載下來的xlsx全是亂碼

平時在前端下載文件有兩種方式,一種是后臺提供一個 下載的http URL,然后用 window.open(URL)或者創(chuàng)建一個a標簽的href屬性下載,另一種就是后臺直接返回文件的二進制內(nèi)容,然后前端轉(zhuǎn)化一下再下載。

由于第一種方式比較簡單,在此不做探討。本文主要講解一下第二種方式怎么實現(xiàn)。

Blob、ajax(axios)
mdn 上是這樣介紹 Blob 的:

Blob 對象表示一個不可變、原始數(shù)據(jù)的類文件對象。Blob 表示的不一定是JavaScript原生格式的數(shù)據(jù)

具體使用方法

axios({
  method: 'post',
  url: '/export',
})
.then(res => {
  // 假設(shè) data 是返回來的二進制數(shù)據(jù)
  const data = res.data
  const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}))
  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = url
  link.setAttribute('download', 'excel.xlsx')
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
})

打開下載的文件,看看結(jié)果是否正確。

一堆亂碼…

一定有哪里不對。

最后發(fā)現(xiàn)是參數(shù) responseType 的問題,responseType 它表示服務器響應的數(shù)據(jù)類型,由于后臺返回來的是二進制數(shù)據(jù),所以我們要把它設(shè)為 arraybuffer(如果后端傳遞過來約定的是blob,那么responseType應該設(shè)置成這個responseType: 'blob')
接下來再看看結(jié)果是否正確。

axios({
  method: 'post',
  url: '/export',
  responseType: 'arraybuffer',
  // responseType: 'blob'
})
.then(res => {
  // 假設(shè) data 是返回來的二進制數(shù)據(jù)
  const data = res.data
  const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}))
  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = url
  link.setAttribute('download', 'excel.xlsx')
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
})

這次沒有問題,文件能正常打開,內(nèi)容也是正常的,不再是亂碼。

根據(jù)后臺接口內(nèi)容決定是否下載文件
作者的項目有大量的頁面都有下載文件的需求,而且這個需求還有點變態(tài)。

具體需求如下

如果下載文件的數(shù)據(jù)量條數(shù)符合要求,正常下載(每個頁面限制下載數(shù)據(jù)量是不一樣的,所以不能在前端寫死)。
如果文件過大,后臺返回 { code: 199999, msg: '文件過大,請重新設(shè)置查詢項', data: null },然后前端再進行報錯提示。
先來分析一下,首先根據(jù)上文,我們都知道下載文件的接口響應數(shù)據(jù)類型為 arraybuffer。返回的數(shù)據(jù)無論是二進制文件,還是 JSON 字符串,前端接收到的其實都是 arraybuffer。所以我們要對 arraybuffer 的內(nèi)容作個判斷,在接收到數(shù)據(jù)時將它轉(zhuǎn)換為字符串,判斷是否有 code: 199999。如果有,則報錯提示,如果沒有,則是正常文件,下載即可。具體實現(xiàn)如下:

axios.interceptors.response.use(response => {
    const res = response.data
    // 判斷響應數(shù)據(jù)類型是否 ArrayBuffer,true 則是下載文件接口,false 則是正常接口
    if (res instanceof ArrayBuffer) {
        const utf8decoder = new TextDecoder()
        const u8arr = new Uint8Array(res)
        // 將二進制數(shù)據(jù)轉(zhuǎn)為字符串
        const temp = utf8decoder.decode(u8arr)
        if (temp.includes('{code:199999')) {
            Message({
                // 字符串轉(zhuǎn)為 JSON 對象
                message: JSON.parse(temp).msg,
                type: 'error',
                duration: 5000,
            })
            return Promise.reject()
        }
    }
    // 正常類型接口,省略代碼...
    return res
}, (error) => {
    // 省略代碼...
    return Promise.reject(error)
})

react fetch(react方案)

const qryurl = `/offapi/liveaum/exportExcelData`;
    fetch(qryurl, {
      method: 'POST',
      credentials: 'include',
      headers: { Accept: 'application/json', 'Content-Type': 'application/json;charset=UTF-8' },
      body: JSON.stringify(params),
    }).then(response => {
      if (response.ok) {
        let downloadFileName = decodeURIComponent(response.headers.get('filename'));
        this.setState({ downloadFileName, downModalShow: true, iconLoading: false });
        response.blob().then(blob => {
          downBlob = blob;
        });
      }
    }).catch(function(err) {
      console.log(err);
      downBlob = null;
      message.warning('暫未查詢到數(shù)據(jù)');
      this.setState({ iconLoading: false })
    });
// 導出文件
  handleOk = () => {
    const link = document.createElement('a');
    link.style.display = 'none';
    link.href = URL.createObjectURL(downBlob);
    link.download = `${this.state.downloadFileName}.xls`;
    document.body.appendChild(link);
    link.click();
    URL.revokeObjectURL(link.href);
    document.body.removeChild(link);
    message.success('下載成功');
    this.onModalclose();
  };

到此這篇關(guān)于JS二進制流文件下載導出(接口返回二進制流)亂碼處理的文章就介紹到這了,更多相關(guān)js二進制文件下載導出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript中的this引用(推薦)

    JavaScript中的this引用(推薦)

    this是javascript的一個關(guān)鍵字,隨著函數(shù)使用場合不同,this的值會發(fā)生變化。這篇文章主要介紹了JavaScript中的this引用的相關(guān)資料,非常不錯,需要的朋友可以參考下
    2016-08-08
  • JavaScript中FontFace對象的使用方式

    JavaScript中FontFace對象的使用方式

    這篇文章主要介紹了JavaScript中FontFace對象的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 微信小程序中獲取用戶手機號授權(quán)登錄詳細步驟

    微信小程序中獲取用戶手機號授權(quán)登錄詳細步驟

    這篇文章主要給大家介紹了關(guān)于微信小程序中獲取用戶手機號授權(quán)登錄的詳細步驟,在微信小程序中開發(fā)者可以通過微信提供的API接口實現(xiàn)用戶登錄和獲取用戶的手機號,需要的朋友可以參考下
    2023-07-07
  • 基于node.js的快速開發(fā)透明代理

    基于node.js的快速開發(fā)透明代理

    服務器端js(Server-Side Javascrpt)很早也就有了,JAVA中也有javascript 的script引擎。
    2010-12-12
  • JS實現(xiàn)點擊Radio動態(tài)更新table數(shù)據(jù)

    JS實現(xiàn)點擊Radio動態(tài)更新table數(shù)據(jù)

    這篇文章主要介紹了JS實現(xiàn)點擊Radio動態(tài)更新table數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • QQ強制聊天功能代碼(加強版,兼容QQ2010)

    QQ強制聊天功能代碼(加強版,兼容QQ2010)

    QQ強制聊天功能代碼,腳本之家以前也發(fā)布過,但已經(jīng)不能用了,這個是新版本,經(jīng)過測試,完全兼容新版本的qq.
    2010-06-06
  • js?scrollTop如何到達指定位置

    js?scrollTop如何到達指定位置

    很早之前就想分享這篇心得,幸之今天能在這里完成,好了,話不多說,進入正題。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 純HTML5制作圍住神經(jīng)貓游戲-附源碼下載

    純HTML5制作圍住神經(jīng)貓游戲-附源碼下載

    圍住神經(jīng)貓游戲是一款基于html5、jquery、typescript等技術(shù)開發(fā)的游戲,非常好玩,感興趣的朋友快來圍觀吧,體驗一把,下面給大家分享使用html5如何制作圍住神經(jīng)貓游戲-附源碼下載,有需要的朋友可以參考下
    2015-08-08
  • 微信小程序常用賦值方法小結(jié)

    微信小程序常用賦值方法小結(jié)

    這篇文章主要介紹了微信小程序常用賦值方法,結(jié)合實例形式總結(jié)了微信小程序局部變量、全局變量及data對象屬性賦值相關(guān)操作技巧,需要的朋友可以參考下
    2019-04-04
  • JS遍歷數(shù)組及打印數(shù)組實例分析

    JS遍歷數(shù)組及打印數(shù)組實例分析

    這篇文章主要介紹了JS遍歷數(shù)組及打印數(shù)組的方法,結(jié)合實例形式分析JavaScript數(shù)組的遍歷與打印輸出相關(guān)技巧,需要的朋友可以參考下
    2016-01-01

最新評論