摘要:最近做了個(gè)實(shí)現(xiàn)網(wǎng)頁縮略圖的項(xiàng)目,其中不免需要用到網(wǎng)頁截屏。選擇好方案后還是踩了不少坑,第一個(gè)就是我得想辦法讓它和通信,不然我沒法通過前端只傳一個(gè)需要被截圖的鏈接給就能實(shí)現(xiàn)截圖。
最近做了個(gè)實(shí)現(xiàn)網(wǎng)頁縮略圖的項(xiàng)目,其中不免需要用到網(wǎng)頁截屏。
一開始想的是看看能不能在前端直接實(shí)現(xiàn)截圖,因?yàn)閃eb端的截圖并生成圖片并不算是一個(gè)高頻的需求,網(wǎng)上資料自然也不算多,查來查去,發(fā)現(xiàn)JavaScript 目前還不能實(shí)現(xiàn)真正意義上的網(wǎng)頁截屏,未來如果能夠?qū)崿F(xiàn),也一定是瀏覽器提供了相關(guān)接口,JS 去調(diào)用這些接口。
既然js不能實(shí)現(xiàn)真正意義上的截屏,那我們能做的只有通過拿到DOM的一些信息利用canvas來生成圖片。
如何將dom轉(zhuǎn)換成canvas圖片?自然是要一點(diǎn)點(diǎn)畫到canvas里,想想都是件麻煩事。網(wǎng)上找來找去看看有沒有現(xiàn)成的輪子,找到了html2canvas,通過分析?niklasvh/html2canvas,梳理了其大致的思路:
遍歷頁面中的所有元素,提取DOM節(jié)點(diǎn),填充到一個(gè)rederList,并附加是否為頂層元素/包含內(nèi)容的容器等信息
通過提取的css屬性和元素的層級(jí)信息將rederList排序,計(jì)算出一個(gè)canvas的renderQueue
遍歷renderQueue,將css樣式轉(zhuǎn)為setFillStyle可識(shí)別的參數(shù),依據(jù)nodeType調(diào)用相對(duì)應(yīng)canvas方法,將節(jié)點(diǎn)對(duì)應(yīng)到 canvas 上。
這個(gè)方案聽起來就很復(fù)雜了,無論是排序優(yōu)先級(jí)的計(jì)算還是從css到canvas的轉(zhuǎn)換,毫無疑問都是些巨麻煩的事,尤其是放在真實(shí)的業(yè)務(wù)場(chǎng)景里,DOM模版中往往會(huì)包含復(fù)雜的樣式與排版,html2canvas 足足用了20多個(gè)js來實(shí)現(xiàn)這層轉(zhuǎn)換,復(fù)雜成度可見一斑。不過這個(gè)庫封裝的不錯(cuò),使用起來比較簡(jiǎn)單:
html2canvas(document.body).then(function(canvas) { canvas.id = "screenshotCanvas" document.body.appendChild(canvas) });
此時(shí),頁面的截圖已經(jīng) append 到了 body 中了。雖然過程是很復(fù)雜,但是已經(jīng)有了這些輪子,我們了解原理就好,人家有現(xiàn)成的庫可以用,那咱們就不要再花費(fèi)力氣去造輪子,不好玩。
說了這么多這個(gè)canvas的方案,但是我最終還是沒有選擇它,因?yàn)槲业木W(wǎng)頁里面有不少圖片,都是外域資源,而這套方案我認(rèn)為最大的問題就是:無法跨域加載資源 (雖然html2canvars補(bǔ)充了方案來彌補(bǔ)這個(gè)問題,但是對(duì)于我的項(xiàng)目實(shí)現(xiàn)起來成本都太高)
忘了說,在研究html2canvars的過程中我還發(fā)現(xiàn)了一個(gè)庫叫rasterizeHTML.js。知乎的意見反饋功能里面的截圖就是使用的這個(gè)庫,原理有點(diǎn)類似,不過使用的是svg,所以我還是沒有選擇它,它也沒法繞過跨域請(qǐng)求資源這個(gè)問題。
最后只能從node端使用 phantomJS 來實(shí)現(xiàn)了。phantomJS 它提供了一個(gè)截屏函數(shù),通過它可以整屏獲取頁面截圖,而且他支持的格式也比較多:JPG/PNG/GIF/PDF。通過簡(jiǎn)單的兩句命令就可以把一個(gè)網(wǎng)頁截取下來:
// 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 之后執(zhí)行下上面的文件:
phantomjs render.js
調(diào)用完你會(huì)發(fā)現(xiàn),圖片已經(jīng)保存到了同目錄下。
選擇好方案后還是踩了不少坑,第一個(gè)就是我得想辦法讓它和node通信,不然我沒法通過前端只傳一個(gè)需要被截圖的鏈接給node就能實(shí)現(xiàn)截圖。
于是接著在網(wǎng)上找,發(fā)現(xiàn)又是這么復(fù)雜,動(dòng)不動(dòng)就是websocket的方式等,只能接著找輪子,還好有諸多前輩已經(jīng)實(shí)現(xiàn)好了,萬花叢中選擇了一個(gè)比較適合我項(xiàng)目的叫做phantom的庫解決了這問題。
走到這一步以為萬事具備了,然后開干,發(fā)現(xiàn)截了張白屏給我,一開始以為是要截的網(wǎng)頁數(shù)據(jù)沒有加載完,于是delay了一會(huì)再去截圖,發(fā)現(xiàn)還是白屏,這就很絕望了。
走到這一步再放棄就不好玩了,最終經(jīng)過長(zhǎng)久的debug發(fā)現(xiàn),原來phantomJS沒有支持到promise,而我網(wǎng)頁請(qǐng)求數(shù)據(jù)走的是fetch api,phantomJS模擬瀏覽器打開我的網(wǎng)頁,數(shù)據(jù)一直請(qǐng)求不到,打開的網(wǎng)頁是個(gè)空的,截圖自然就變成白屏了。
最后的結(jié)局是好的,就是再對(duì)promise 做了一下polyfill,實(shí)現(xiàn)了我想要的截圖。過程也是好的,作為前端菜鳥,能學(xué)到的簡(jiǎn)直不能再多了。(最近看了看剛出來的Headless chrome,或許以后的截圖我就用不到phantom了)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85146.html
摘要:最近在實(shí)現(xiàn)一個(gè)功能,需求如下前提當(dāng)前頁面無彈窗頁面任意位置執(zhí)行粘貼讀取剪切板中的截屏數(shù)據(jù)上傳截圖首先還是從網(wǎng)上找相關(guān)的例子。找到了上的專欄文章獲取剪切板內(nèi)容,控制圖片粘貼。 最近在實(shí)現(xiàn)一個(gè)功能,需求如下: 前提:當(dāng)前頁面無彈窗 頁面任意位置執(zhí)行粘貼 讀取剪切板中的截屏數(shù)據(jù) 上傳截圖 首先還是從網(wǎng)上找相關(guān)的例子。 找到了SF上的專欄文章《js獲取剪切板內(nèi)容,js控制圖片粘貼》。 于是...
摘要:的鏈接在感興趣的同學(xué)可以自行查閱最后總結(jié)當(dāng)返回頭沒有的時(shí)候,使用猜測(cè)出來的編碼一般都是很準(zhǔn)的當(dāng)返回頭里面有的時(shí)候,如果有,則的編碼為的值。截圖自己看把,地址在如果還有猜測(cè)編碼的方法,歡迎留言完 大家爬取網(wǎng)頁的時(shí)候,應(yīng)該都遇到過這種情況? 當(dāng)我打印網(wǎng)頁源代碼的時(shí)候 發(fā)現(xiàn) 全部是亂碼的 showImg(https://segmentfault.com/img/remote/14600000...
摘要:特此寫個(gè)流水賬總結(jié),供自己以后羞恥的回顧。正逢月計(jì)劃辭職回家玩游戲過個(gè)暑假,結(jié)果在如今部門老大的忽悠下加入到了新東家。和組長(zhǎng)兩人繼續(xù)沒晝夜的忙活,最終也按時(shí)交差,上了線。卷土重來,回報(bào)過去的一份念舊,期待的美好,個(gè)人選型入坑。 前言 2017年發(fā)生了太多的事情,結(jié)了婚,住進(jìn)了新家,成功的播了種,當(dāng)上了準(zhǔn)爸爸。公司也蒸蒸日上搬進(jìn)了高大上的寫字樓。前端的坑越來越大,都來不及填。特此寫個(gè)流水...
摘要:昨天上午,我發(fā)布了業(yè)界第一款性能統(tǒng)計(jì)分析框架。同時(shí),這個(gè)工具也是學(xué)習(xí)瀏覽器加載渲染網(wǎng)頁過程和性能優(yōu)化的一個(gè)利器,因此我們也可以把他作為一個(gè)強(qiáng)大的學(xué)習(xí)輔助工具,不至于讓我們?cè)跇颖具^少的情況下得到錯(cuò)誤的結(jié)論。 昨天上午10:00,我發(fā)布了業(yè)界第一款「性能統(tǒng)計(jì)分析框架」Hiper。 截止到2018年6月6號(hào)20:00分,已經(jīng)500個(gè)star了,同時(shí)項(xiàng)目也沖上了Github新熱門榜單第三名的位...
閱讀 2587·2021-11-25 09:43
閱讀 1988·2019-08-30 13:56
閱讀 1254·2019-08-30 12:58
閱讀 3453·2019-08-29 13:52
閱讀 785·2019-08-26 12:17
閱讀 1490·2019-08-26 11:32
閱讀 963·2019-08-23 13:50
閱讀 1327·2019-08-23 11:53