老板要在公司大屏显示器上全屏展示监控页面。
于是每天早上去公司第一件事就是把大屏开机并手动登录手动全屏。可是有时候老板去的比我早,发现大屏没开,被老板说这个简单的东西都实现不了。当然可以。
自动开关机
开始研究电脑的自动开关机。电脑设置每天自动开机(手把手教你设置电脑自动开关机) - 路途号 (lutu88.com)
开机自动启动浏览器
开机自动启动浏览器并携带账号密码。win10开机自启动浏览器,打开指定网页_自招的博客-CSDN博客_开机启动浏览器指定网页
还算比较很顺利。网上都能找到设置方法。
绕过验证码
接下来绕过验证码,登录时不传验证码,传一串机器码,保证这个码是唯一的。服务端设置白名单,将机器码放入白名单。如果机器码在白名单中,则绕过验证码校验。
机器码可以有很多方式生成,我们使用的fingerprint2.js。
// 获取机器码
function getFingerprint(callback) {
var excludes = {
userAgent: true,
audio: true,
enumerateDevices: true,
fonts: true,
fontsFlash: true,
webgl: true,
canvas: true
}
Fingerprint2.get({ excludes: excludes }, function (components) {
var values = components.map(function (component) {
return component.value;
});
var murmur = Fingerprint2.x64hash128(values.join(''), 31);
callback(murmur);
});
}
getFingerprint(console.log) // 获取机器指纹码
自动登录
进入登录页面,获取query参数,如果url中携带了账号密码,尝试自动登录。
var searchParams = {} // 用来存query参数
// 获取query参数,存入searchParams
window.location.search.substr(1).split('&').forEach(function name(params) {
var arr = params.split('=')
searchParams[arr[0]] = arr[1]
})
if (searchParams.username && searchParams.password) {
// 登录地址中携带了账号密码,执行自动登录操作
getFingerprint(function (fingerprint) {
login({
username: searchParams.username,
password: searchParams.password,
fingerprint: fingerprint
});
});
}
自动全屏
首先想到的是document.requestFullScreen()
经过一番折腾,全屏API调用不成功,后来发现好像需要触发事件才可以,于是new Event() 也试了,还是不行。
因为 requestFullScreen 这个方法只能在用户交互或者设备方向改变的时候调用,否则将会失败。requestFullScreen MDN
因为是自动启动的浏览器,没有用户事件,浏览器端js肯定是解决不了这个问题了。
最终选用VB脚本,可以直接运行在windows。
可以使用vb脚本模拟 F11按键来全屏,也可以使用Chrome提供的启动参数 --start-fullscreen 来全屏启动。因为大屏纯展示,没有用户操作,所以最终选用添加启动参数 --kiosk 以演示模式启动。
Dim delayer
Set delayer = CreateObject("WScript.Shell")
WScript.sleep 8000 ' 等待8s
Dim username
username = "用户名"
Dim password
password = "密码!"
Dim browser
browser = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
Dim env
env = "http://xxx.com" ' 域名
' 全屏启动浏览器
delayer.run """" + browser + """ -kiosk " + env + "/login.html?_=" & DateDiff("s", #1/1/1970#, Now()) & "&username=" + username + "&password=" + password,0,FALSE
Set delayer = Nothing
WScript.quit
全屏启动搞定
奔溃自动重启
因为机器配置很低,32位操作系统2G内存。跑着跑着页面就奔溃了。只在这个机器上可以复现。最终经过长时间的跟踪发现是不停的追加DOM元素导致的内存溢出。问题解决后奔溃的概率小了很多,但还是会出现。
找问题优化的同时,也考虑怎么最快的发现奔溃并恢复。
最终采用心跳的方式,监测浏览器是否正常运行,30s无响应就重新执行VBScript启动浏览器。
// 浏览器端
// 确保本地存在心跳服务后,持续发起心跳请求
fetch('http://localhost:3000/heartbeat').then(() => {
// 浏览器端每隔10s发送一次请求
setInterval(() => {
fetch('http://localhost:3000/heartbeat')
}, 10 * 1000)
}).catch(console.log)
// 服务端代码
const express = require('express')
const cmd = require('node-cmd')
const app = express()
let i = 0
setInterval(() = {
if (i++ >= 30) {
// 30s无心跳,重新启动浏览器
cmd.run('./startBrowser.vbs')
i = 0
}
}, 1000)
app.use((request, response, next ) => {
response.header( 'Access-Control-Allow-Origin' , '*')
next()
})
app.get('/heartbeat', function (req, res) {
i = 0
res.send('ok')
})
app.listen(3000, function () {
console.log('server running, port 3000')
})
将 vbs 脚本和nodejs脚本放入指定文件夹。确保拥有node运行环境。
开机启动项更改为如下脚本
' start.vbs
Set ws = CreateObject("WScript.Shell")
ws.Run "C:/xxx/node.exe C:/desktop/show/main.js",0
最终完成老板的需求。奔溃问题没有彻底解决,持续跟进中(老板给买的机器配置太低了)。奔溃后的及时重启给加了一层保障。机器码可以使用别的更好的方式,用fingerprint2.js 生成的指纹码更新浏览器版本就会改变,也可以跟账号密码一样从url带过来。心跳监测也可以用websocket持久连接,可以更及时的发现奔溃问题。
如有不足,还请指教。欢迎讨论交流。