首页 > 解决方案 > 如何从 express.js 运行服务器与客户端共享桌面屏幕?

问题描述

我正在使用 express.js 和非无头 puppeteer 开发应用程序。

它运作良好。但是最终用户看不到运行 puppeteer 自动化的 Chromium 选项卡屏幕。显而易见的原因是 Chromium 在 (express.js) 服务器上运行。

目前,javascript 正在努力向服务器端的 puppeteer 发送信息并返回响应以在 index.html 中显示它。

我正在寻找在 index.html 中显示 Chromium 屏幕的解决方案。也许在 iframe 标签或类似的东西内。记住 Chromium 是在服务器端运行的。

基本上我需要与最终用户共享 Chromium 屏幕。

可能吗?

渴望拆分 index.html

下面是一个简单的 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;
}

标签: javascriptnode.jsexpresspuppeteerchromium

解决方案


推荐阅读