初步折腾 Playwright,被 AI 带偏

2025-06-17 · 周二一般中雨

来我司搞前端开发,什么奇奇怪怪的东西和需求都要做。这次需要做一个使用服务端完成渲染 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 的范畴,如果他们确认要这么干用无头浏览器的方案,就让后端去具体实现吧!

Paul

Paul

特立独行的一只前端菜狗。这篇日记编写大概耗时了 30 分钟,内容均为个人原创,并采用 CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!如本站内容对你有所帮助的话,不妨 捐助支持 一下?

奇趣音乐盒技术源于 Kico Player
Emmm,这里是歌词君