react+ts實現點擊按鈕下載圖片,兼容IE

(適用於react+ts)
第一種


<FontAwesomeIcon
 icon={faDownload}
onClick={() => this.downloadCurrentImage()}
className="ImageFrame-downloadIcon"
/>
private downloadCurrentImage() {
    const image = new Image();
   image.crossOrigin = "anonymous";
    image.onload = () => {
      const canvas = document.createElement("canvas");
      canvas.width = image.width;
      canvas.height = image.height;
     const context = canvas.getContext("2d") as CanvasRenderingContext2D;
      context.drawImage(image, 0, 0, image.width, image.height);
      const url = canvas.toDataURL("image/png");
     const a = document.createElement("a");
      a.download = "a.png"
      a.href = url;
      a.click();
    };
    image.src = XXXXX;
  }

存在的問題  a.download 只兼容firefox和chrome.  在IE瀏覽器中無效果
然後我嘗試了判斷瀏覽器,如果是IE和microSoft Edge, 就用window.open(url)
 

/** get current browser */
  private getBrowser() {
    const userAgent = navigator.userAgent;
    const browserArr = ["Opera", "IE", "Edge", "FF", "Safari", "Chrome"];
    const isOpera = userAgent.includes("Opera");
    //IE
    const isIE = userAgent.includes("compatible") && userAgent.includes("MSIE") && !isOpera;
    const isEdge = userAgent.includes("Edge");
    const isFF = userAgent.includes("Firefox");
    // safari
    const isSafari = userAgent.includes("Safari") && !userAgent.includes("Chrome");
    // chrome
    const isChrome = userAgent.includes("Chrome") && userAgent.includes("Safari");
    const agentArr = [isOpera, isIE, isEdge, isFF, isSafari, isChrome];
    for (let i = 0; i < agentArr.length; i++) {
      if (agentArr[i] === true) {
        return browserArr[i];
      }
    }
  }


const currentBrowser = this.getBrowser()
if(currentBrowser === "IE" ||currentBrowser  === "Edge") {
//直接打開圖片的路徑
window.open(XXXX)
}

但是並沒有解決根本問題, 我從網上查了很多資料,最終完成了功能,僅此記錄
 

//觸發下載事件
 <div  onClick={() => this.downloadCurrentImage()} />

 /**download current image as PNG */
  private downloadCurrentImage() {
    const browserName = this.getBrowser();
    const {id} = {...this.props};
    //在我的項目中獲取imageSrc是這樣的,請根據自己的項目內容來寫;
    const imageSrc = this.props.imageUrlProvider.getImageUrl(this.props.id);
    this.convertUrlToBase64(imageSrc).then((base64) => {
      if (browserName === "IE" || browserName === "Edge") {
        const blob = this.convertBase64UrlToBlob(base64 as string);
        //第二個參數是下載文件名
        window.navigator.msSaveBlob(blob, `${id}.png`);
      } else {
        const a = document.createElement("a");
        //下載文件名:我是用id
        a.download = `${id}.png`;
        a.href = imageSrc;
        a.click();
      }
    });
  }

/**
   * convert image's url to base64
   * @param url `string` image's url
   */
  private convertUrlToBase64(url: string) {
    return new Promise((resolve, reject) => {
      const images = new Image();
      images.crossOrigin = "Anonymous";
      images.onload = () => {
        const canvas = document.createElement("canvas");
        canvas.width = images.width;
        canvas.height = images.height;
        const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
        ctx.drawImage(images, 0, 0, images.width, images.height);
        resolve(canvas.toDataURL("image/png", 1));
      };
      images.onerror = () => {
        reject(new Error("get image error"));
      };
      images.src = url;
    });
  }

  /**
   * convert image's base64 url to Blob
   * @param base64`string` image's base64 url
   */
  private convertBase64UrlToBlob(base64: string) {
    //baseArr[0]: head of base64, image's type(eg: "image/png")
    const baseArr = base64.split(",");
    //baseArr[1]: after removing the head of base64, the rest of content
    const newCode = window.atob(baseArr[1]);
    const newArr = new Uint8Array(newCode.length);
    for (let i = 0; i < newCode.length; i++) {
      newArr[i] = newCode.charCodeAt(i);
    }
    //type可以根據需求修改
    return new Blob([newArr], {type: "image/png"});
  }

  /** get current browser */
  private getBrowser() {
    const userAgent = navigator.userAgent;
    const browserArr = ["Opera", "IE", "Edge", "FF", "Safari", "Chrome"];
    const isOpera = userAgent.includes("Opera");
    //IE
    const isIE = userAgent.includes("compatible") && userAgent.includes("MSIE") && !isOpera;
    const isEdge = userAgent.includes("Edge");
    const isFF = userAgent.includes("Firefox");
    // safari
    const isSafari = userAgent.includes("Safari") && !userAgent.includes("Chrome");
    // chrome
    const isChrome = userAgent.includes("Chrome") && userAgent.includes("Safari");
    const agentArr = [isOpera, isIE, isEdge, isFF, isSafari, isChrome];
    for (let i = 0; i < agentArr.length; i++) {
      if (agentArr[i] === true) {
        return browserArr[i];
      }
    }
  }

歡迎大佬指導


參考文章:
js 通過 blob 類文件對象下載圖片,修改圖片保存的名字(兼容式寫法)

js 圖片 base64 與 blob 與 img實例 互相轉換

 base64 和 Blob 相互轉換


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章