如何使用Puppeteer监听history.pushstate事件?

4
使用Puppeteer,是否可以监听浏览器历史记录API,如history.pushState、history.replaceState或history.popState,这些常用于单页应用程序框架路由器(如react-router)的后台,以便在视图之间导航?我不需要page.waitForNavigation(options),因为它不是真正意义上的导航,也不是一个侦听器。此外,我希望能够捕获传递给历史函数的参数,如data、title和url。

Puppeteer的常见问题解答中提到:“从Puppeteer的角度来看,‘导航’是任何改变页面URL的行为。除了正常的导航,在此之外,还包括锚点导航和History API的使用。”因此,您可以使用page.waitForNavigation(options)来处理History API事件。 - Volodymyr
无法与 react-router 一起使用,这会引发超时错误... - user10531084
这回答解决了你的问题吗?[puppeteer:如何等待单页应用程序中的页面?](https://dev59.com/mFUM5IYBdhLWcg3wAsVF) - ggorlen
1个回答

5
您可以使用 waitForNavigation 监听 History API 事件。例如:
const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.goto('https://www.google.com');

const [navResponse] = await Promise.all([
    page.waitForNavigation(),
    page.evaluate(() => { history.pushState(null, null, 'imghp') }),
])

console.log(navResponse) // null as per puppeteer docs
await browser.close();

根据文档,导航响应为空。 "如果导航到不同的锚点或由于历史记录API使用而导航,则导航将解析为null。"
如果您正在使用哈希导航,可以根据puppeteer-examples中的说明创建路由更改的事件监听器。
  await page.exposeFunction('onHashChange', url => page.emit('hashchange', url));
  await page.evaluateOnNewDocument(() => {
    addEventListener('hashchange', e => onHashChange(location.href));
  });

  // Listen for hashchange events in node Puppeteer code.
  page.on('hashchange', url => console.log('hashchange event:', new URL(url).hash));

使用react-routerpage.waitForNavigation()将会在_TimeoutError: Navigation Timeout Exceeded_中结束。 - user10531084
2
我以为这个问题在https://github.com/GoogleChrome/puppeteer/commit/fafd156d7bd9941131ab31f5af7cf047e728142c中已经解决了 - 我已经更新了我的答案,包括如何监听哈希导航变化的方法。 - Matt Shirley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接