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 MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...