来我司搞前端开发,什么奇奇怪怪的东西和需求都要做。这次需要做一个使用服务端完成渲染 SVG 智能图形(不知道这是什么?请看 智能图形,正式发布!)的需求,只有两套方案,一个是改造原程序需要花时间,另外一个就是无头浏览器。在 AI 的建议下尝试了无头浏览器方案 Playwright,类似于 Puppeteer,模拟正常用户操作但没有任何用户界面。
我让 AI 来实现我的需求,在页面上注入脚本,执行一段 window.postMessage
代码,之后原来的页面应用将会请求数据,请求完成后开始渲染,渲染成功后页面将会出现某个 DOM 元素,最后再次执行一段 window.postMessage
代码,让应用生成对应 SVG 图的 Base64 版本数据,返回到服务端侧。
const browser = await playwright.chromium.launch({ headless: false });
const context = await browser.newContext();
const finalDataPromise = new Promise(async (resolve, reject) => {
// 服务端接收数据,页面应用发送过来
await context.exposeFunction("onGraphicData", (data) => {
console.log("onGraphicData", data);
});
// 这段代码不起作用,浏览器啥都没输出
await context.addInitScript(() => {
console.log("Inited");
window.addEventListener("message", (event) => {
// requestImageData 接收到后会发送另一条消息
if (event.data && event.data.type) {
window.onGraphicData(event.data);
}
});
});
});
const page = await context.newPage();
await page.goto("http://localhost:5173", { waitUntil: "domcontentloaded" });
// 发送初始化信息
await page.evaluate((payload) => {
window.postMessage(payload, "*");
}, graphicInitPayload);
// 等待图形加载完成
await page.waitForSelector(".editor-controls", { timeout: 30000 });
// 请求图片数据
await page.evaluate(() => {
window.postMessage({ type: "requestImageData" }, "*");
});
const graphicData = await finalDataPromise;
console.log("Graphic data received.");
上述代码是 AI 生成的(我做了简化,可能实际上无法直接运行)但是它自带 Bug,你发现了吗?AI 写的东西,果然还是仅供参考,完全没接触过的东西直接让它写,还是特别容易踩坑。
这段代码执行不成功,其实是 context.addInitScript
这里的代码根本就没执行,没打印出 Inited
。它的执行时机应该在页面加载出来之前,没细看过 文档 直接问 AI(这里我看在浏览器的控制台并没有显示出来,可能是什么原因),它居然认为是前端页面执行了 console.clear
,而不是它没有被执行。
当然实际上上面的代码还能做减法,例如 requestImageData
之后,直接让页面应用调用 onGraphicData
就可以了。接下来就看如何实现 Base64 图片内容的转存,当然这已经不属于 Demo 的范畴,如果他们确认要这么干用无头浏览器的方案,就让后端去具体实现吧!