javascript - 如何从 express.js 运行服务器与客户端共享桌面屏幕?
问题描述
我正在使用 express.js 和非无头 puppeteer 开发应用程序。
它运作良好。但是最终用户看不到运行 puppeteer 自动化的 Chromium 选项卡屏幕。显而易见的原因是 Chromium 在 (express.js) 服务器上运行。
目前,javascript 正在努力向服务器端的 puppeteer 发送信息并返回响应以在 index.html 中显示它。
我正在寻找在 index.html 中显示 Chromium 屏幕的解决方案。也许在 iframe 标签或类似的东西内。记住 Chromium 是在服务器端运行的。
基本上我需要与最终用户共享 Chromium 屏幕。
可能吗?
下面是一个简单的 express.js 应用程序,它采用 index.html 中所选选项的国家名称并显示相应的首都。资本截图取自 Chromium 在服务器端运行 puppeteer 自动化。我不知道如何在 index.html 中共享铬屏幕。
应用程序
|_server.js
|_public
|_index.html
|_scraper.js
|_styles.css
npm i express puppeteer
服务器.js
/**
* server.js
**/
const express = require('express');
const app = express();
const http = require('http').Server(app);
const bodyParser = require('body-parser');
const puppeteer = require('puppeteer');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static('public'));
// STARTING PUPPETEER NON-HEADLESS
var browser
(async () => {
browser = await puppeteer.launch({ headless: false });
})();
app.get('/', (req, res) => {
res.sendFile('index.html', { root: __dirname + '/public'});
});
app.post('/', (req, res) => {
let nation = req.body.nation;
scrapeGoogle(nation)
.then(capital => {
res.status(200).json({ capital: capital });
})
.catch(err => {
res.end()
})
});
const scrapeGoogle = async (nation) => {
const page = await browser.newPage();
await page.goto('https://google.com');
await page.type('input.gLFyf.gsfi', `capital of ${nation}`);
await Promise.all([
page.keyboard.press('Enter'),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
await page.waitForSelector('#search');
const element = await page.$('#search > div > div > div');
let capital_base64 = await element.screenshot({ encoding: "base64" });
await page.close();
return Promise.resolve(capital_base64);
}
http.listen(3000, () => console.log('Example app listening on port 3000!'))
索引.html
<!DOCTYPE html>
<html>
<head>
<title>Puppeteer</title>
<link rel="stylesheet" href="styles.css">
</head>
<body style="text-align: center;">
<label for="natio">What's the capital of: </label>
<select id="nation">
<option value="USA">USA</option>
<option value="Brazil">Brazil</option>
</select>
<button type="submit" id="go">Go</button>
<div id="loader" style="text-align: center;" hidden></div>
<div id="answer" hidden><img src="" alt="" id="image"></div>
<script src="scraper.js"></script>
</body>
</html>
刮刀.js
document.addEventListener("DOMContentLoaded", (event) => {
let button = document.getElementById("go");
button.addEventListener("click", function(e) {
document.getElementById('loader').hidden = false;
document.getElementById("image").src = "";
let nation = document.getElementById("nation").value;
fetch('/', {
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ nation: nation })
})
.then(res => res.json())
.then(json => {
let capitalBase64 = json.capital;
document.getElementById("image").src = `data:image/png;base64, ${capitalBase64}`;
document.getElementById('loader').hidden = true;
document.getElementById('answer').hidden = false;
})
.catch(() => {
alert('An error has occurred');
document.getElementById('loader').hidden = true;
})
});
});
样式.css
#loader {
border: 8px solid #f3f3f3;
border-radius: 50%;
border-top: 8px solid #3498db;
width: 32px;
height: 32px;
animation: spin 2s linear infinite;
margin: auto;
margin-top: 32px;
}
@keyframes spin {
0% {
transform: rotate(0deg)
}
100% {
transform: rotate(360deg)
}
}
#image {
margin-top: 32px;
}
解决方案
推荐阅读
- java - 如何在 ChannelHandlerContext netty 4.1.50 中存储值
- active-directory - Microsoft 文档 - “Win32 AD”和“Windows 协议 AD”有什么区别?
- c - 使用 struct 时 C 中的 for 循环出现问题
- excel - 使用字符串通过变量名控制 VBA 表单
- c - 如何将 Pcie 区域模拟为持久内存?
- cmake - 当依赖文件被修改时,如何让 CMake 重新运行 add_custom_command?
- sql-server - 从标志更改为新列时有效地提取列值
- sql-server - 如何通过 AWS RDS SQL Server 主用户执行 sp_changedbowner?
- elasticsearch - 弹性搜索设计 - 改进空间
- amazon-web-services - 在 AWS 的安全组中编辑 IP 地址时遇到问题