4月13號(hào),phantomJS 的主要維護(hù)者突然宣布不干了,當(dāng)時(shí)我正在為如何把前端代碼運(yùn)行到后端發(fā)愁,正想著用用 phantomJS 的時(shí)候,出了這檔子事。仔細(xì)看看他說的,大意是 google 也來插一腳了,更穩(wěn)定,更牛,那我就功成身退啦。好吧,感謝辛勞付出,我看看 google 到底整了啥幺蛾子。
chrome 在 59 的版本中做了一個(gè) headless 模式,可以在這里查看原文。大致的功能就是能在服務(wù)器跑一個(gè) chrome 瀏覽器,具有 chrome 的絕大部分功能。Amazing?。?!這下子都不用模擬瀏覽器環(huán)境了,直接就整了一個(gè)瀏覽器的環(huán)境,值得折騰一下。
然后,我就落入了一個(gè)深基坑。。。。廢話少說,直接告訴大家如何開玩。
1.準(zhǔn)備 Chrome
首先,你需要一個(gè)支持 Headless 模式的 Chrome。
Linux 平臺(tái)請(qǐng)安裝最新的 dev 版本,macOS 平臺(tái)請(qǐng)安裝最新的 金絲雀 版本,Win 平臺(tái),我還沒試過,知道的朋友可以分享一下。
2.運(yùn)行 headless chrome
安裝好之后,運(yùn)行如下命令:
Linux:
google-chrome-unstable --headless --remote-debugging-port=9222 --disable-gpu https://shimo.im
macOS:
/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --headless --remote-debugging-port=9222 https://shimo.im/
--headless 就是開啟 headless 模式。
--remote-debugging-port=9222 這是開啟 Chrome 的端口是 9222,這樣子 Chrome 就類似于微服務(wù)一樣啦。
--disable-gpu 不使用 gpu,既然是在后端運(yùn)行的 Chrome 當(dāng)然不需要 gpu 啦。
最后的網(wǎng)址隨意填寫,我在這寫的是我們的產(chǎn)品—— 石墨文檔
隨意打開一個(gè)瀏覽器,輸入 http://localhost:9222 可以得到如下的效果
看到這個(gè)就證明,你成功開啟了 headless chrome 的服務(wù)
3.調(diào)用 chrome
調(diào)用 Chrome 需要用到一個(gè) node 模塊——chrome-remote-interface
官網(wǎng)的例子足夠本地測試使用,我們團(tuán)隊(duì)在實(shí)際使用過程中發(fā)現(xiàn)了不少坑。
第一個(gè)坑是遠(yuǎn)程連接,CDP 中提供了 remote 的配置來允許你遠(yuǎn)程連接 Chrome,筆者第一次使用時(shí),就遇上了一個(gè) bug,Headless Chrome 還沒有完美對(duì)接,我剛想著給作者提一個(gè) bug。
作者立馬修了。。。。。為他點(diǎn)贊,但是在實(shí)際使用過程中,還是需要設(shè)置好 nginx 的反向代理
第二個(gè)坑則是協(xié)議 (protocol),這個(gè)協(xié)議決定你能用什么接口去調(diào)用 chrome 的服務(wù),具體的 API 在這里。如何獲得協(xié)議?參見源碼,因?yàn)榭偹苤脑?,下載協(xié)議很慢,大家先下載下來,然后在 protocol 的選項(xiàng)里寫上
protocol: JSON.parse(fs.readFileSync('protocol.json'))
就可以了。
ps: 作者說可以用
chrome-remote-interface protocol -r > protocol.json
這個(gè)命令生成協(xié)議,但是我生成的是一個(gè)錯(cuò)誤的文件。。。。
本地的連接調(diào)試非常簡單,如果你想遠(yuǎn)程調(diào)用的話,需要這樣子設(shè)置
'use strict';
const CDP = require('chrome-remote-interface');
const fs = require('fs');
const protocol = JSON.parse(fs.readFileSync('protocol.json'));
const
options = {
host: "[https://chrome.com](https://chrome.com/)", // 域名或者 IP 都行
port: 443, // 按照實(shí)際情況來
remote: true, // 遠(yuǎn)程連接需要設(shè)置為 true
protocol, // client 可以使用的方法
secure: true // https 的話需要這是這個(gè)
};
function *test() {
const client = yield CDP(options);
console.log('success!');
client.close();
}
client 提供了非常多的接口,比如操作頁面的 Page,有興趣的同學(xué)可以和我們石墨團(tuán)隊(duì)深入淺出的交流一下。