1. 程式人生 > 其它 >Linux指令_曾佳豪

Linux指令_曾佳豪

檔案下載

  1. 下載介面返回 File 檔案
  2. 下載介面返回 base64 字串

下載介面返回 File 檔案

location.href 下載

這種下載請求方式不會被 axios 攔截進行統一處理,相當於直接在瀏覽器位址列訪問,不會攜帶 token。因此需要在後端給介面配置白名單才能被訪問

/**
 * http://127.0.0.1/download 是下載介面地址
*/
downloadFile(){
    window.location.href = 'http://127.0.0.1/download'
}

利用 a 標籤 的 href 屬性下載檔案

    downloadFile() {
      console.log("檔案下載");
      this.$axios({
        url: "/download",
        method: "get",
        // responseType: "ArrayBuffer", // 檔案下載 預設格式 ArrayBuffer
        responseType: "blob", // 設定拿到的響應資料的格式
      }).then((res) => {
        console.log(res.data);
        const blob = res.data;
        let url = URL.createObjectURL(blob);
        console.log(url);
        let link = document.createElement("a");
        link.href = url;
        link.download = "img.jpg";
        link.style.visibility = "hidden";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    },

下載介面返回 base64 字串

base64 檔案,利用 a 標籤下載

base64 檔案轉 blob,blob 轉 ObjectUrl,利用 a 標籤下載

/**
 * content 為檔案的 base64 碼,
 * fileName 為下載到系統的檔名
*/
downloadFile(fileName, base64Url) {
    // base64轉blob
    function base64ToBlob(code) {
      const parts = code.split(';base64,');
      const contentType = parts[0].split(':')[1];   // 獲取檔案型別
      const raw = window.atob(parts[1]);
      const rawLength = raw.length;
      const uInt8Array = new Uint8Array(rawLength);
      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
      }
      return new Blob([uInt8Array], { type: contentType });
    }
    const blob = this.base64ToBlob(base64Url);

    if (window.navigator.msSaveOrOpenBlob) { // 判斷客戶端是否允許直接下載blob,有msSaveOrOpenBlob方法表示允許下載,此方法ie適用
        navigator.msSaveBlob(blob, fileName);
    }
    else {  // 客戶端不允許下載,需要借用a標籤的href屬性下載檔案
        const link = document.createElement('a');   // 建立a標籤
        link.href = window.URL.createObjectURL(blob); // 指定下載的內容 URL.createObjectURL(blob)將blob轉為本地url
        link.download = fileName;   // 指定預設檔名
        //此寫法相容可火狐瀏覽器
        // 在Chrome瀏覽器下,模擬點選建立的<a>元素即使不append到頁面中,也是可以觸發下載的,但是在Firefox瀏覽器中卻不行,因此,上面的funDownload()方法有一個appendChild和removeChild的處理,就是為了相容Firefox瀏覽器。
        document.body.appendChild(link);    // 掛載a標籤
        const evt = document.createEvent("MouseEvents");    // 建立滑鼠事件
        evt.initEvent("click", false, false);   // 初始化滑鼠事件 為單擊事件 阻止冒泡 阻止預設事件
        link.dispatchEvent(evt);    // 觸發evt事件
        document.body.removeChild(link);    // 移除節點
    }
},

下普通文字檔案,利用 a 標籤下載

/**
 * content 指需要下載的文字或字串內容,
 * filename 指下載到系統中的檔名稱
 */
let downloadFile = function (content, filename) {
  // 建立隱藏的可下載連結
  let eleLink = document.createElement('a')
  eleLink.download = filename
  eleLink.style.display = 'none'
  // 字元內容轉變成blob地址
  let blob = new Blob([content])
  eleLink.href = URL.createObjectURL(blob)
  // 觸發點選
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然後移除
  document.body.removeChild(eleLink)
}

使用 canvas 下載頁面上展示的圖片

domImg 為下載的 img DOM 節點,fileName 為下載到系統的檔名

let downloadFile = function (domImg, filename) {
  // 建立隱藏的可下載連結
  let eleLink = document.createElement('a')
  eleLink.download = filename
  eleLink.style.display = 'none'
  // 圖片轉base64地址
  let canvas = document.createElement('canvas')
  let context = canvas.getContext('2d')
  let width = domImg.natureWidth
  let height = domImg.natureHeight
  context.drawImage(domImg, 0, 0)
  // 如果是PNG圖片,則context.toDataURL('image/png')
  eleLink.href = context.toDataURL('image/jpeg')
  // 觸發點選
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然後移除
  document.body.removeChild(eleLink)
}

ie9 及以上 base64 檔案下載

downloadFile(){
  // 判斷是否為ie瀏覽器
  if(!!window.ActiveXObject || "ActiveXObject" in window){
      // 是ie瀏覽器
      this.downloadFileForIE(url,fileName)
  }else{
      // 是標準瀏覽器
      // ......
  }
  downloadFileForIE(url,fileName){
      let blobStr = window.atob(url,split(',')[1])  // atob() 方法用於解碼使用 base-64 編碼的字串 為blob字串
      let n = blobStr.length
      let u8arr = new Uint8Array(n) // Uint8Array陣列表示一個8位無符號整數陣列,陣列長度為n
      while(n--){
          u8arr[n]=blobStr.charCodeAt(n)   // charCodeAt()將字元轉換為Unicode編碼
      }
      let blob = new Blob([u8arr])  // 將字元陣列 轉為blob字串
      window.navigator.msSaveOrOpenBlob(blob,imgName) //下載或開啟blob檔案,下載到系統的檔名為imgName
  }
}

實戰演練

Vue + express 實現檔案下載

前端

<el-button type="primary" @click="download">專案筆記下載</el-button>
    download() {
      console.log("檔案下載");
      this.$axios({
        url: "/download",
        method: "get",
        // responseType: "ArrayBuffer", // 檔案下載 預設格式 ArrayBuffer
        responseType: "blob", // 設定拿到的響應資料的格式
      }).then((res) => {
        console.log(res.data);
        const blob = res.data;
        let url = URL.createObjectURL(blob);
        console.log(url);
        let link = document.createElement("a");
        link.href = url;
        link.download = "img.jpg";
        link.style.visibility = "hidden";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      });
    },

後端

exports.download = (req, res) => {
  res.download('./public/img/aaa-1648172747193.webp')
}