把Html插入canvas實現網頁截圖

將DOM內容HTML繪製到畫布中是有可能的但如何有把握地, 並且安全地實現它,就應該按照規範行事。你不能把HTML畫到canvas上。相反,你需要使用一個SVG圖像,其中包含你想要呈現的內容。可以使用<foreignobject> 元素包含HTML內容,之後把這個svg繪製到你的canvas中。

 

唯一真正棘手的事情可能是創建SVG圖像,所有你需要做的是創建一個包含XML字符串的SVG,然後按照下面的步驟構造一個Blob

 

blob對象的媒體類型mime爲 “image/svg+xml”.

 <svg> 元素.

在svg元素中包含 <foreignobject> 元素.

(格式化好的) HTML ,被包裹到<foreignobject>中.

 

如上所述通過使用一個object URL,我們可以內聯HTML而不是從外部源加載它。當然,如果你喜歡你可以使用外部源,只要域與原始文件相同,比如:

 

<!DOCTYPE html>

<html>

<body>

<p><canvas id="canvas"style="border:2px solid black;" width="200"height="200"></canvas>

<script>

var canvas =document.getElementById("canvas");

var ctx =canvas.getContext("2d");

var data = "<svgxmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +

            "<foreignObject width='100%' height='100%'>" +

               "<divxmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +

                 "<em>I</em>like <span style='color:white; text-shadow:0 0 2pxblue;'>cheese</span>" +

               "</div>" +

            "</foreignObject>" +

          "</svg>";

var DOMURL = self.URL || self.webkitURL ||self;

var img = new Image();

var svg = new Blob([data], {type:"image/svg+xml;charset=utf-8"});

var url = DOMURL.createObjectURL(svg);

img.onload = function() {

   ctx.drawImage(img, 0, 0);

   DOMURL.revokeObjectURL(url);

};

img.src = url;

</script>

</body>

</html>

 

data變量設置了SVG圖像的內容(這包括HTML)我們希望繪製到我們的canvas中。通過調用 newImage()我們建立一個新的html <img> 元素,添加數據進去,指定一個object URL, 之後在圖片onload的時候調用 drawImage() 來把圖片繪製到畫布中.

 

您可能想知道這種方式是否安全,擔心canvas會讀取敏感數據。答案是這樣的:這個解決方案的實現依賴的SVG圖像是非常嚴格的。SVG圖像不允許加載任何外部資源,即使似乎來自同一個域。資源(如柵格圖像(如JPEG圖像)或<iframe>s 需要用 data: URIs來內聯引入。

 

此外,你不能在一個SVG圖像中引入腳本文件,所以沒有從其他腳本訪問DOM的風險,而且DOM元素在SVG圖像中不能接收事件的輸入,所以沒有辦法通過把隱私信息加載到一個表單控件(如一個文件的完整路徑 <input> 元素)然後渲染出來,之後通過讀取像素把這些信息取出。

 

訪問過的鏈接風格並不應用於SVG圖像中呈現的鏈接,所以歷史信息也不能被檢索,本地的主題也不呈現在SVG圖像中,這使得它很難確定用戶的平臺。

 

生成的canvas元素是純淨的,意味着你可以通過調用 toBlob(function(blob){…})來返回canvas的blob ,或者toDataURL()來返回 Base64-編碼的 data: URI。

 

SVG必須是合法的XML,你需要解析並把HTML轉爲規範的符合格式的。下面的代碼可以很方便的解析HTML

 

var doc =document.implementation.createHTMLDocument("");

doc.write(html);

 

// You must manually set the xmlns if youintend to immediately serialize the HTML

// document to a string as opposed toappending it to a <foreignObject> in the DOM

doc.documentElement.setAttribute("xmlns",doc.documentElement.namespaceURI);

 

// Get well-formed markup

html = (newXMLSerializer).serializeToString(doc);

 

本文爲Anyforweb技術分享博客,需要了解網站建設及更多web應用相關信息,請訪問anyforweb.com。

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