1. 程式人生 > >通過base64實現圖片下載功能(基於vue)

通過base64實現圖片下載功能(基於vue)

code 不支持 dea methods navi text 完整 瀏覽器支持 stat

1. 使用場景

當我們處理圖片下載功能的時候,如果本地的圖片,那麽是可以通過canvas獲得圖片的base64的,方法如下。但是如果圖片的url存在跨域問題的話,下面的方法將行不通,這時候我們可以另辟蹊徑,將後臺的同學,將圖片以base64的形式進行返回。

function getBase64(url){
    //通過構造函數來創建的 img 實例,在賦予 src 值後就會立刻下載圖片,相比 createElement() 創建 <img> 省去了 append(),也就避免了文檔冗余和汙染
    var Img = new Image(),
        dataURL='';
    Img.src=url;
    Img.onload=function(){ //要先確保圖片完整獲取到,這是個異步事件
        var canvas = document.createElement("canvas"), //創建canvas元素
            width=Img.width, //確保canvas的尺寸和圖片一樣
            height=Img.height;
        canvas.width=width;
        canvas.height=height;
        canvas.getContext("2d").drawImage(Img,0,0,width,height); //將圖片繪制到canvas中
        dataURL=canvas.toDataURL('image/jpeg'); //轉換圖片為dataURL
    };
}

2. 處理base64,進行下載

處理base64的時候有兩點要註意,一個是對ie瀏覽器的處理,一個是對火狐瀏覽器的處理

2-1. 我們首先直接處理base64(基於vue)

1.由於後臺返回的是純base64,如果要完成圖片的下載功能,必須加上一個前綴

<template>
  <a
    :href="prefixBase64 + qrBase64"
    download="qrcode.png"
    class="qrcode"
  >
    <img src="static/img/load.png">
  </a>
</template>

<script>
  ...
  data () {
    return {
      qrBase64: '', // 二維碼對應的base64(在方法裏面進行獲取)
      prefixBase64: 'data:image/png;base64,', // base64前綴
    }
  }
  ...
</script>

2.采用這種方式可以很好的支持chrome、Firefox、opera、Safari,但是不支持ie,所以我們下面單獨處理ie瀏覽器

2-2. 處理ie瀏覽器

1.修改代碼如下

<template>
  <a
    @click.stop.prevent="handleDownloadQrIMg"
    class="qrcode"
  >
    <img src="static/img/load.png">
  </a>
</template>
<script>
export default {
  methods: {
    // 點擊下載圖片
    handleDownloadQrIMg() {
      // 這裏是獲取到的圖片base64編碼,這裏只是個例子哈,要自行編碼圖片替換這裏才能測試看到效果
      const imgUrl = this.prefixBase64 + this.qrBase64;
      // 如果瀏覽器支持msSaveOrOpenBlob方法(也就是使用IE瀏覽器的時候),那麽調用該方法去下載圖片
      if (window.navigator.msSaveOrOpenBlob) {
        let bstr = atob(imgUrl.split(",")[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        let blob = new Blob([u8arr]);
        window.navigator.msSaveOrOpenBlob(blob, "chart-download" + "." + "png");
      } else {
        // 這裏就按照chrome等新版瀏覽器來處理
        let a = document.createElement("a");
        a.href = imgUrl;
        a.setAttribute("download", "chart-download");
        a.click();
      }
    }
  }
};
</script>

2.ok,ie的問題解決了,但是火狐的又不行了

2-3. 兼容方法

1.結合上面兩種檢測方法,我們只要可以判斷瀏覽器是火狐,然後單獨處理就可以實現我們的兼容性了

<template>
  <div>
    <a
      v-if="!isFirefox"
      @click.stop.prevent="handleDownloadQrIMg"
      class="qrcode"
    >
      <img src="static/img/load.png">
    </a>
    <a
      v-if="isFirefox"
      :href="prefixBase64 + qrBase64"
      download="qrcode.png"
      class="qrcode"
    >
      <img src="static/img/load.png">
    </a>

  </div>

</template>

<script>
export default {
  data() {
    return {
      qrBase64: "", // 二維碼對應的base64(在方法裏面進行獲取)
      prefixBase64: "data:image/png;base64,", // base64前綴
      isFirefox: false
    };
  },
  mounted() {
    // 判斷瀏覽器是否是火狐
    if (navigator.userAgent.indexOf("Firefox") > 0) {
      this.isFirefox = true;
    }
  },
  methods: {
    // 點擊下載圖片
    handleDownloadQrIMg() {
      // 這裏是獲取到的圖片base64編碼,這裏只是個例子哈,要自行編碼圖片替換這裏才能測試看到效果
      const imgUrl = this.prefixBase64 + this.qrBase64;
      // 如果瀏覽器支持msSaveOrOpenBlob方法(也就是使用IE瀏覽器的時候),那麽調用該方法去下載圖片
      if (window.navigator.msSaveOrOpenBlob) {
        let bstr = atob(imgUrl.split(",")[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        let blob = new Blob([u8arr]);
        window.navigator.msSaveOrOpenBlob(blob, "chart-download" + "." + "png");
      } else {
        // 這裏就按照chrome等新版瀏覽器來處理
        let a = document.createElement("a");
        a.href = imgUrl;
        a.setAttribute("download", "chart-download");
        a.click();
      }
    }
  }
};
</script>

通過base64實現圖片下載功能(基於vue)