前言:最近作前端資源監控,看了不少例子,沒有達到想要的效果。首先的槽點是PhantomJS的官方文檔,真雞肋,其次是網上的例子,多數是介紹PhantomJS的用法,而並無介紹怎麼完整的去實現,跟官方文檔好像也沒啥區別......前端
1、實現了什麼?
本文只作一個簡單的例子,獲取網址加載時間,旨在實現一種思路,而不是很複雜的功能。node
主要流程: web
前端在頁面加載時調用node接口 -> 將URL返回給接口 -> node獲取url,而後經過子進程(child_process)啓動系統命令 -> 啓動PhantomJS
-> PhantomJS打開url指定的網頁,計算加載時間 -> 返回給node接口 -> 接口處理數據 -> 入庫數據庫
2、主要實現npm
一、前端獲取urlapi
let param = {'url': window.location.protocol + '//' + window.location.host};瀏覽器
將url做爲參數傳遞給接口。網絡
二、NodeJS獲取前端傳遞過來的url並啓動phantomjs打開url,數據獲取並處理架構
本文用的是sails框架。app
首先是寫models定義字段:ResourceMonitor.js
module.exports = {
connection: '數據庫名',
tableName: '表名',
autoCreatedAt: true,
autoUpdatedAt: true,
attributes: {
id: {
type: 'integer',
primaryKey: true,
autoIncrement: true
},
webAddress: {
type: 'string'
},
loadingTime: {
type: 'string'
}
}
}
而後寫服務: resourceMonitorService.js
module.exports = {
async create(resourceMonitor){
try {
try {
if (resourceMonitor.id) {
let oldResourceMonitor = await ResourceMonitor.findOne({id: resourceMonitor.id});
Object.assign(oldResourceMonitor, resourceMonitor);
oldResourceMonitor.save(function (err) {
if (err) throw err;
return oldResourceMonitor;
})
} else {
return ResourceMonitor.create(resourceMonitor);
}
} catch (err) {
throw err;
}
} catch (err) {
throw err;
}
}
}
接着是controller: resourceMonitorController.js
const Cmd = require('cmd')
module.exports = {
async create(req, res){
try {
let url = req.body['url']
let resource = await Cmd.resourceMonitorPhantom(url);//啓動phantomJS
if (!resource) return;
resource = resource.replace(/[\s\n\r]+/g, "")//正則去除空格換行符回車符
let loadingTime = resource.match(/total:(\S*)ms/)[1] + ' ms';//正則匹配'total:'和'ms'之間的全部非空白內容,並在返回結果後面加上'ms'
let webAddress = resource.match(/webAddress:(\S*)total:/)[1];//正則匹配'webAddress:'和'total:'之間的全部非空白內容
let resourceMonitor = {webAddress, loadingTime}
if (!resourceMonitor) {
sails.log.error("參數異常 " + JSON.stringify(resourceMonitor))
return res.send({code: -1, msg: "參數異常"})
}
resourceMonitorService.create(resourceMonitor).then(function (data) {
return res.send({code: 1, msg: "success", data: data})
}).catch(function (err) {
sails.log.error("create resourceMonitor err" + err)
return res.send({code: -1, msg: "get resourceMonitor list err"})
})
} catch (err) {
sails.log.error("create resourceMonitor failure" + err)
return res.send({code: -1, msg: "create resourceMonitor failure"})
}
}
}
NodeJS命令行啓動PhantonJS的方法:cmd.js
//用的是node子進程中的execSync同步方法,能夠等phantomjs處理完數據返回之後才執行接下來的內容
let execSync = require('child_process').execSync;
module.exports = {
async resourceMonitorPhantom(url){
try {
let resourceMonitorCmd = `phantomjs ./phantom/resourceMonitorPhantom.js ${url}`;
let resourceMonitorOut = await execSync(resourceMonitorCmd).toString();//因爲phantomjs返回等數據是二進制流buffer,因此處理稱字符串
return resourceMonitorOut;
} catch (err) {
throw err;
}
}
}
PhantomJS獲取資源加載時間:resourceMonitorPhantom.js
var page = require('webpage').create();
var system = require('system');
var address;
if (system.args.length === 1) {
console.log(system.args)
phantom.exit();
} else {
var t = Date.now();
address = system.args[1];
page.open(address, function (status) {
if (status !== 'success') {
console.log('fail to load the address');
} else {
t = Date.now() - t;
console.log('webAddress:' + address + 'total:' + t + 'ms');
}
phantom.exit();
});
}
3、涉及的框架及運行環境
一、NodeJS
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。 Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。 Node.js 的包管理器 npm,是全球最大的開源庫生態系統。
官網:https://nodejs.org/
二、Sails
Sails.js (or Sails) is a Model-View-Controller (MVC) web application framework developed atop the Node.js environment, released as free and open-source software under the MIT License. It is designed to make it easy to build custom, enterprise-grade Node.js web applications and APIs. Emulating the MVC architecture of other frameworks, like Ruby on Rails it offers similar pattern and familiarity, reducing the cognitive burden when switching between other frameworks/languages.
Sails.js (or Sails)是一個開發的模型-視圖-控制器(MVC)web應用程序框架的節點。js的環境,在MIT許可下免費和開源軟件的發佈。它的目的是使它容易構建定製的,企業級節點。js web應用程序和api。效仿其餘框架的MVC架構,像Ruby on Rails提供了相似的模式和熟悉,減小認知負擔當切換其餘框架/語言。
官網:http://sailsjs.com/
三、 PhantomJS
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
PhantomJS,腳本化的WebKit內核的無頭瀏覽器,支持各類web標準:DOM處理CSS選擇器,JSON,Canvas,SVG。
簡單的說,就是一個沒有界面的webkit內核瀏覽器,只能在命令行下使用。能夠作不少事,好比:生成網頁截圖、抓去網頁數據、獲取網絡資源加載時間等。
官網:http://phantomjs.org/