摘要:最近做了個實現網頁縮略圖的項目,其中不免需要用到網頁截屏。選擇好方案后還是踩了不少坑,第一個就是我得想辦法讓它和通信,不然我沒法通過前端只傳一個需要被截圖的鏈接給就能實現截圖。
最近做了個實現網頁縮略圖的項目,其中不免需要用到網頁截屏。
一開始想的是看看能不能在前端直接實現截圖,因為Web端的截圖并生成圖片并不算是一個高頻的需求,網上資料自然也不算多,查來查去,發現JavaScript 目前還不能實現真正意義上的網頁截屏,未來如果能夠實現,也一定是瀏覽器提供了相關接口,JS 去調用這些接口。
既然js不能實現真正意義上的截屏,那我們能做的只有通過拿到DOM的一些信息利用canvas來生成圖片。
如何將dom轉換成canvas圖片?自然是要一點點畫到canvas里,想想都是件麻煩事。網上找來找去看看有沒有現成的輪子,找到了html2canvas,通過分析?niklasvh/html2canvas,梳理了其大致的思路:
遍歷頁面中的所有元素,提取DOM節點,填充到一個rederList,并附加是否為頂層元素/包含內容的容器等信息
通過提取的css屬性和元素的層級信息將rederList排序,計算出一個canvas的renderQueue
遍歷renderQueue,將css樣式轉為setFillStyle可識別的參數,依據nodeType調用相對應canvas方法,將節點對應到 canvas 上。
這個方案聽起來就很復雜了,無論是排序優先級的計算還是從css到canvas的轉換,毫無疑問都是些巨麻煩的事,尤其是放在真實的業務場景里,DOM模版中往往會包含復雜的樣式與排版,html2canvas 足足用了20多個js來實現這層轉換,復雜成度可見一斑。不過這個庫封裝的不錯,使用起來比較簡單:
html2canvas(document.body).then(function(canvas) { canvas.id = "screenshotCanvas" document.body.appendChild(canvas) });
此時,頁面的截圖已經 append 到了 body 中了。雖然過程是很復雜,但是已經有了這些輪子,我們了解原理就好,人家有現成的庫可以用,那咱們就不要再花費力氣去造輪子,不好玩。
說了這么多這個canvas的方案,但是我最終還是沒有選擇它,因為我的網頁里面有不少圖片,都是外域資源,而這套方案我認為最大的問題就是:無法跨域加載資源 (雖然html2canvars補充了方案來彌補這個問題,但是對于我的項目實現起來成本都太高)
忘了說,在研究html2canvars的過程中我還發現了一個庫叫rasterizeHTML.js。知乎的意見反饋功能里面的截圖就是使用的這個庫,原理有點類似,不過使用的是svg,所以我還是沒有選擇它,它也沒法繞過跨域請求資源這個問題。
最后只能從node端使用 phantomJS 來實現了。phantomJS 它提供了一個截屏函數,通過它可以整屏獲取頁面截圖,而且他支持的格式也比較多:JPG/PNG/GIF/PDF。通過簡單的兩句命令就可以把一個網頁截取下來:
// render.js var webPage = require("webpage") var page = webPage.create() page.viewportSize = { width: 1920, height: 1080 } page.open("http://www.iqiyi.com", function start(status) { page.render("iqiyi_home.jpeg", {format: "jpeg", quality: "100"}) phantom.exit() })
安裝 phantomjs 之后執行下上面的文件:
phantomjs render.js
調用完你會發現,圖片已經保存到了同目錄下。
選擇好方案后還是踩了不少坑,第一個就是我得想辦法讓它和node通信,不然我沒法通過前端只傳一個需要被截圖的鏈接給node就能實現截圖。
于是接著在網上找,發現又是這么復雜,動不動就是websocket的方式等,只能接著找輪子,還好有諸多前輩已經實現好了,萬花叢中選擇了一個比較適合我項目的叫做phantom的庫解決了這問題。
走到這一步以為萬事具備了,然后開干,發現截了張白屏給我,一開始以為是要截的網頁數據沒有加載完,于是delay了一會再去截圖,發現還是白屏,這就很絕望了。
走到這一步再放棄就不好玩了,最終經過長久的debug發現,原來phantomJS沒有支持到promise,而我網頁請求數據走的是fetch api,phantomJS模擬瀏覽器打開我的網頁,數據一直請求不到,打開的網頁是個空的,截圖自然就變成白屏了。
最后的結局是好的,就是再對promise 做了一下polyfill,實現了我想要的截圖。過程也是好的,作為前端菜鳥,能學到的簡直不能再多了。(最近看了看剛出來的Headless chrome,或許以后的截圖我就用不到phantom了)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85146.html
摘要:最近在實現一個功能,需求如下前提當前頁面無彈窗頁面任意位置執行粘貼讀取剪切板中的截屏數據上傳截圖首先還是從網上找相關的例子。找到了上的專欄文章獲取剪切板內容,控制圖片粘貼。 最近在實現一個功能,需求如下: 前提:當前頁面無彈窗 頁面任意位置執行粘貼 讀取剪切板中的截屏數據 上傳截圖 首先還是從網上找相關的例子。 找到了SF上的專欄文章《js獲取剪切板內容,js控制圖片粘貼》。 于是...
摘要:的鏈接在感興趣的同學可以自行查閱最后總結當返回頭沒有的時候,使用猜測出來的編碼一般都是很準的當返回頭里面有的時候,如果有,則的編碼為的值。截圖自己看把,地址在如果還有猜測編碼的方法,歡迎留言完 大家爬取網頁的時候,應該都遇到過這種情況? 當我打印網頁源代碼的時候 發現 全部是亂碼的 showImg(https://segmentfault.com/img/remote/14600000...
摘要:昨天上午,我發布了業界第一款性能統計分析框架。同時,這個工具也是學習瀏覽器加載渲染網頁過程和性能優化的一個利器,因此我們也可以把他作為一個強大的學習輔助工具,不至于讓我們在樣本過少的情況下得到錯誤的結論。 昨天上午10:00,我發布了業界第一款「性能統計分析框架」Hiper。 截止到2018年6月6號20:00分,已經500個star了,同時項目也沖上了Github新熱門榜單第三名的位...
閱讀 1759·2021-11-25 09:43
閱讀 1953·2019-08-30 13:56
閱讀 1214·2019-08-30 12:58
閱讀 3412·2019-08-29 13:52
閱讀 755·2019-08-26 12:17
閱讀 1452·2019-08-26 11:32
閱讀 934·2019-08-23 13:50
閱讀 1297·2019-08-23 11:53