1. 程式人生 > 其它 >web通過檔案連結直接下載檔案給到使用者,而不是先跳轉預覽

web通過檔案連結直接下載檔案給到使用者,而不是先跳轉預覽

場景

  • 已知一個檔案的儲存連結,有下載操作,使用者可以下載該檔案,但是如果簡單地通過window.location.href = file.path來實現的話,結果是web跳轉到一個預覽該檔案的新頁面,而且還需要手動點下載檔案才能真正下載到本地。
  • 同理,a標籤的href改成file.path也是同樣的結果。

問題

  • 現在希望使用者不用預覽檔案,而是在第一次下載操作之後就直接把檔案下載到本地。

實現

  • 用XMLHttpRequest直接請求file.path,然後設定responseType能夠控制請求返回的資料型別,預設是text型別,設定成blob型就能下載檔案,還有arraybuffer, json等型別,什麼場景用什麼型別,具體情況具體分析,比如我只是想拿到檔案文字內容做展示
    ,那就直接text型別,比如我有一堆檔案需要打包到zip裡一起給到使用者,那就用arraybuffer型別...... 所有型別見
  • 這裡直接用axios封裝就好了
    import axios from 'axios'
    
    export function getFile (path, type = 'text') {
      // path = '把路徑字首改成配置的proxy字首,本地需要代理' // 本地把字首換成代理字首
      // 生產環境則是原path,但是需要後臺配置跨域
      return new Promise((resolve, reject) => {
        axios.get(path, {
          responseType: type
        }).then((res) => {
          resolve(res.data) // 這裡的res.data就是我們需要的檔案對應responseType型別的資料了
        }).catch(err => {
          reject(err)
        })
      })
    }
    
  • 然後就能非同步處理自己的邏輯了,這裡只舉下載檔案的例子,具體情況具體分析
    // vue methods
    dwonload (record) {
      getFile(record.download_url, 'blob').then((file) => { // 直接下載檔案傳blob型
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = (e) => {
          const a = document.createElement('a')
          // 獲取檔名fileName
          a.download = record.file_name
          a.href = e.target.result
          document.body.appendChild(a)
          a.click() // 這樣就觸發瀏覽器下載檔案了
          document.body.removeChild(a)
        }
      })
    }