首頁 > 軟體

JS實現將圖片URL轉base64範例詳解

2023-04-02 06:02:08

背景介紹

最近有個需求是將部分DOM生成圖片上傳到伺服器,這裡就直接用之前專案使用的 html-to-image

然而,這次與上次不同的是有一個圖片;其實,html-to-image也支援了存在圖片的DOM生成截圖(embed-images)。

出現意外

不出意外的就該出意外了:

很容易理解,就是跨域了請求了。注意,這裡本來之前使用img標籤是能正常請求的,並且也不用加crossorigin屬性。 在呼叫html-to-image中加上mode: 'no-cors'依然不行。

進入正題吧

然後就想自己搞轉base64吧,各種百度谷歌出來了

const image2Base64 = (url: string) => new Promise((resolve, reject) => {
  if (!url) {
    resolve('');
    return;
  }
  const img = new Image();
  img.crossOrigin = 'anonymous';
  img.src = url;
  img.onload = () => {
    const canvas = document.createElement('canvas');
    canvas.width = img.width;
    canvas.height = img.height;
    const ctx = canvas.getContext('2d');
    ctx?.drawImage(img, 0, 0);
    const data = canvas.toDataURL();
    resolve(data);
  };
  img.onerror = () => {
    reject('');
  };
});

特別需要注意的是:img標籤屬性是crossorigin,new Image需使用crossOrigin。 如果不設定crossOrigin會造成另一個問題:

在用canvas呼叫toDataURL方法中出錯了。

然後又是各種百度谷歌,發現MDN有個權威又無語的解釋:

提煉一下哈:指定crossorigin的影象,在canvas呼叫中不會出現tainted錯誤。

其實上面已經能解決大多數的問題了:

對,沒猜錯,事情沒有絕對的,還是有個例的:

不知是這個圖片伺服器咋設定的,各種吧啦吧啦溝通也不給設定跨域白名單啥的,只能自己想辦法了。

nodejs中間層轉

const http = require('http');
http.get(url, (res) => {
  const chunks = [];
  let size = 0;
  res.on('data', (chunk) => {
    chunks.push(chunk);
    size += chunk.length;
  });
  res.on('end', () => {
    const data = Buffer.concat(chunks, size);
    const base64Data = data.toString('base64');
    return base64Data;
  });
});

結果,完美解決。

總結

  • 使用crossOrigin能解決大多數情況
  • 如果能在圖片伺服器加跨域白名單最好
  • 終極大招就是nodejs轉
  • nodejs弊端:對於圖片無法使用CDN,對伺服器壓力增大,慎用

以上就是JS實現將圖片URL轉base64範例詳解的詳細內容,更多關於JS圖片URL轉base64的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com