Html2canvas——圖片空白的幾種排查解決方案

来源:https://www.cnblogs.com/xikui/p/18085166
-Advertisement-
Play Games

問題:用html2canvas生成畫布圖片,再轉成pdf。生成圖片時內容結構里的圖片顯示空白。 解決: 首先伺服器設置圖片允許跨域,如阿裡雲騰訊雲配置跨域規則。其次圖片設置crossOrigin=“anonymous”,並且拿到圖片地址加隨機參數如 src +‘?v=’ + Math.random( ...


問題:用html2canvas生成畫布圖片,再轉成pdf。生成圖片時內容結構里的圖片顯示空白。
解決: 首先伺服器設置圖片允許跨域,如阿裡雲騰訊雲配置跨域規則。其次圖片設置crossOrigin=“anonymous”,並且拿到圖片地址加隨機參數如 src +‘?v=’ + Math.random()防止使用緩存,再者html2canvas設置屬性useCORS, allowTaint為true。

  下列文章來源該篇

 

一、工作原理

html2canvas庫的工作原理並不是真正的“截圖”,而是讀取網頁上的目標DOM節點的信息來繪製canvas,所以它並不支持所有的css屬性

二、在 img標簽中載入外部圖片

前提是外部圖片允許跨域,需要伺服器設置

以nginx為例,response-header內要存在Access-Control-Allow-Orgin:xxxx(可以是*,安全性要求比較高的可以根據主功能變數名稱自定義),如果該資源所在的web-server是不支持跨域的,保存圖片是不會成功的。

img標簽設置跨域

當html2canvas中生成的截圖中包含外部圖片,那麼外部圖片在引入的時候就需要設置允許跨域。

另外,通過 ‘img’ 載入的圖片,瀏覽器預設情況下會將其緩存起來,在canvas中用到圖片時,就會直接使用緩存圖片,不會再重新發請求。又因為瀏覽器本身不會有跨域問題,所以如果‘img’沒有設置 crossorigin 屬性,那麼就會出現跨域問題,圖片不能再次被覆用到 canvas 上去的。

1. 'img’標簽設置crossOrigin屬性
<img crossOrigin="anonymous" src={imgSrc} alt="img" />

這是最簡單的方法,讓圖片可以復用到canvas上。

2. chrome設置
<img src={imgSrc} alt="img" />

瀏覽器設置 disable cache,這種方法需要設置瀏覽器屬性,不推薦。

 

3. 使用JS載入圖片
const [imgBase, setImgBase] = useState("");
<img src={imgBase} alt="img" />
  const downloadIamge = imgsrc => {
    //下載圖片地址和圖片名
    let image = new Image();
    // 解決跨域 Canvas 污染問題
    image.setAttribute("crossOrigin", "anonymous");
    image.onload = function() {
      let canvas = document.createElement("canvas");
      canvas.width = image.width;
      canvas.height = image.height;
      let context = canvas.getContext("2d");
      context.drawImage(image, 0, 0, image.width, image.height);
      let url = canvas.toDataURL("image/png"); //得到圖片的base64編碼數據
      setImgBase(url);
    };
    image.src = imgsrc;
  };

 

這種方法能避免使用圖片緩存,在開發過程中,使用js方式請求圖片資源,最好每一次都加個隨機數,以保證源都是最新的,不走緩存。

三、在 html2canvas 中使用
 const createImg = async id => {
     const dom = document.getElementById(id);
     const config = {
          useCORS: true,
          width: dom.offsetWidth,
          height: dom.offsetHeight,
          scrollX: 0,
          scrollY: 0,
          x: 0,
          y: 0,
        };
const data = await html2canvas(dom, config).then(canvas =&gt; {
  canvas.id = "mycanvas";

  document.body.appendChild(canvas);
  const mycanvas = document.getElementById("mycanvas");
  mycanvas.style.display = "none";
  mycanvas.style.position = "fixed";
  mycanvas.style.top = "0px";
  mycanvas.style.left = "0px";
  mycanvas.style.zIndex = "9999";

  let imgData = mycanvas.toDataURL("png");
  imgData = imgData.replace(fixType("png"), "image/octet-stream");
  const file = dataURLtoFile(imgData, "poster.png");

  return file;
});

return data;
};

 

四、html2canvas設置

使用外部圖片就會面臨跨域的問題,html2canvas也需要設置屬性。

1. 允許畫布圖片跨域
confit = { useCORS: true }

 

2. 允許外部圖片污染畫布
confit = { allowTaint: true } 

 

使用上面兩種方法就可以讓外部圖片顯示在畫布上,雖然方法2可以讓外部圖片顯示在畫布上,但是卻不能調用 toBlob(), toDataURL() 或 getImageData() 方法,調用它們會拋出安全錯誤。

五、可能出現的問題
1. html2canvas生成的圖片無法顯示

可能是使用緩存圖片,有以下解決方法

  • 在 Chrome 的調試器中,在 network 面板中,勾選 disable cache 選項,再重新載入圖片
  • 圖片的訪問地址加個隨機數
  • 將圖片url轉成base64
2. html2canvas生成的圖片顯示空白

如果是出現了空白,那有可能是轉成圖片的部分出現滾動條且是在彈窗中展示,需要設置相關滾動高度。
或者有可能是dom不對,請保證dom是要截圖那個元素的父元素

 const dom = document.getElementById(id);
 const config = {
    useCORS: true,
    windowHeight:modal.scrollHeight + 24 + 100,//獲取y方向頁麵包含滾動條的高度,24和100為padding,margin
    width: dom.offsetWidth + 48,//48為padding值
    height: dom.clientHeight + 400,//可見高度+padding+margin
    y: window.pageYOffset + 100,//滾動條高度修複
    scrollX: 17
 };

 

3. ‘img’ 加上crossOrigin="anonymous"之後圖片無法顯示

這個有可能是瀏覽器緩存導致了,可以試試重新載入資源,也可以在資源的請求路徑後加上時間戳重新載入。

六、參考
  1. 中文文檔
  2. canvas.toDataURL()報錯的解決方案全都在這了
  3. 一個關於image訪問圖片跨域的問題
  4. canvas.toDataURL()報錯的解決方案全都在這了
  5. html2canvas生成圖片
  6. html2canvas截圖空白問題
  7. html2canvas生成pdf頁面空白
  8. 基於html2canvas實現網頁保存為圖片及圖片清晰度優化
   
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Android 逆向(四) - adb常用逆向命令 本篇文章繼續記錄下adb 的一些常用逆向命令. 1: adb shell ps 該命令可以查看進程信息. 用法: adb shell ps |grep [pname] zh@zh:~/workSpace$ adb shell ps USER PID ...
  • linux 入門(四) 1: 文件夾下所有文件的大小和詳細信息 du -h --max-depth=1 | sort -hr du命令可以查看文件夾(文件)占用的磁碟大小 ls命令可以查看文件的詳細信息,包括文件大小。 該命令可以按照文件夾(文件)大小的降序排列,並以易讀的方式顯示文件夾(文件)大小 ...
  • 一.引言 在當前的移動開發生態中,跨平臺框架如uni-app因其高效、靈活的特點受到了開發者們的青睞。同時,隨著物聯網技術的飛速發展,智能列印設備已成為許多業務場景中不可或缺的一環。今天,我們就來探討如何使用uni-app輕鬆對接馳騰品牌的智能印表機,實現無線列印功能。無論您是初學者還是有經驗的開發 ...
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:霜序 本文首發於:https://juejin.cn/post/7299384698882539574 在大數據業務中,時常會出現且或關係邏輯的拼接,有需要做 ...
  • 專註探討UUID的核心原理及其生成機制,並詳細介紹不同版本UUID(如版本1的時間戳+節點ID、版本4的隨機數生成等)背後的數學原理和技術細節。 ...
  • 寫入剪切板 使用 clipboard.js 第三方插件: clipboard.js 安裝clipboard.js yarn yarn add clipboard npm npm install clipboard --save 使用示例(vue) <template> <div> <span v-c ...
  • 目錄一.HTML基本框架二.標題標簽三.段落標簽四.換行與水平線標簽五.文本格式化標簽(加粗、傾斜、下劃線、刪除線)六.圖像標簽擴展:相對路徑,絕對路徑與線上網址七.超鏈接標簽八.音頻標簽九.視頻標簽十.列表標簽十一.表格標簽擴展:表格結構標簽合併單元格十二.表單標簽1.input標簽input占位 ...
  • 一、UDP UDP(User Datagram Protocol),用戶數據包協議,是一個簡單的面向數據報的通信協議,即對應用層交下來的報文,不合併,不拆分,只是在其上面加上首部後就交給了下麵的網路層 也就是說無論應用層交給UDP多長的報文,它統統發送,一次發送一個報文 而對接收方,接到後直接去除首 ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...