微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以忽略“离开站点”吗? Puppeteer无头浏览时出现对话框?

如何解决我可以忽略“离开站点”吗? Puppeteer无头浏览时出现对话框?

我正在使用Puppeteer在网站上测试某些表格。在运行测试时,我发现尝试在页面之间导航时执行被卡住了。我自己进行了一次试运行,意识到由于某些表单输入已更改,而表单没有提交,因此页面正在发出对话框。

该消息显示

Leave site?
Changes you made may not be saved.

有一些明显的解决方法,例如,我可以确保在导航到下一页之前每次都提交表单。但是,理想情况下,我只希望能够完全忽略此对话框,因为我只是在运行测试,并且我不在乎更改不会被保存。

是否可以禁用这些消息?如果没有,是否有办法检查是否打开了一个对话框,然后将其关闭

解决方法

尝试由puppeteer设置window.onbeforeunload = null

await page.evaluate(() => {
  window.onbeforeunload = null;
});
,

为了详细说明 existing answer,您尝试处理的 beforeunload 事件会导致出现一个对话框提示。此对话框的处理方式与 promptalert 相同,使用 page.on("dialog",dialog => ...)

可以检查传递给处理程序的 dialog 对象是否存在 "beforeunload" type,然后您可以根据您的行为调用 dismiss()accept()想。 dismiss() 停留在当前页面,中止导航操作,而 accept() 同意离开网站。

您可能的解决方案是同意与 accept() 一起离开网站:

const puppeteer = require("puppeteer");

let browser;
(async () => {
  const html = `
    <h1>a page that prompts before unload</h1>
    <script>
    window.addEventListener("beforeunload",function (e) {
      e.preventDefault();
      (e || window.event).returnValue = "";
      return "";
    });
    </script>
  `;
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();

  const acceptBeforeUnload = dialog => 
    dialog.type() === "beforeunload" && dialog.accept()
  ;
  page.on("dialog",acceptBeforeUnload); 

  await page.setContent(html);

  await page.goto("https://www.example.com");
  console.log(page.url()); // => => https://www.example.com
})()
  .catch(err => console.error(err))
  .finally(() => browser.close())
;

请注意,使用现有答案中简单地在 window.beforeunload = null 回调中设置 evaluate 的方法不适用于此页面。您可以通过删除 page.on 并在 evaluate 上方添加 page.goto 调用来测试。

但是,对于更复杂的行为,例如动态启用和禁用卸载,evaluate 方法似乎有助于避免中止抛出以及删除关闭处理程序,如本示例所示:

const puppeteer = require("puppeteer");

let browser;
(async () => {
  const html = `
    <h1>a page that prompts before unload</h1>
    <script>
    window.addEventListener("beforeunload",function (e) {
      e.preventDefault();
      (e || window.event).returnValue = "";
      return "";
    });
    </script>
  `;
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();

  const dismissBeforeUnload = dialog => 
    dialog.type() === "beforeunload" && dialog.dismiss()
  ;
  page.on("dialog",dismissBeforeUnload); 

  await page.setContent(html);

  // throws Error: net::ERR_ABORTED at https://www.example.com
  await page.goto("https://www.example.com").catch(() => {});
  console.log(page.url()); // => about:blank

  // add to avoid Error: net::ERR_ABORTED when adding a new handler
  await page.evaluate(() => {
    window.onbeforeunload = null;
  });
  page.off("dialog",dismissBeforeUnload); 
  
  // next unload,we'll accept the dialog
  page.on("dialog",dialog => 
    dialog.type() === "beforeunload" && dialog.accept()
  );
  
  // this navigation will succeed
  await page.goto("https://www.example.com");
  console.log(page.url()); // => https://www.example.com
})()
  .catch(err => console.error(err))
  .finally(() => browser.close())
;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。