You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Puppeteer的waitUntil「networkidle」仅监听XHR(AJAX)请求?

How to Make Puppeteer's "Network Idle" Only Consider XHR Requests

Great question! Unfortunately, Puppeteer's built-in networkidle0 and networkidle2 options don't support filtering by resource type—they monitor all network requests, regardless of whether they're XHR, scripts, stylesheets, etc. But we can build a custom solution to mimic "XHR-only network idle" behavior by manually tracking XHR request activity, which pairs perfectly with your existing request interception code.

Here's a robust implementation:

await page.setRequestInterception(true);
page.on("request", (request) => {
  if (request.resourceType() === "image" || request.resourceType() === "font" || request.resourceType() === "media") {
    console.log("Request intercepted! ", request.url(), request.resourceType());
    request.abort();
  } else {
    request.continue();
  }
});

// Track active XHR requests and wait for idle state
let activeXhrRequests = 0;
let idleTimeout;
const xhrIdlePromise = new Promise(resolve => {
  // Increment count when an XHR starts
  page.on('request', request => {
    if (request.resourceType() === 'xhr') {
      activeXhrRequests++;
      // Reset the idle timer if a new XHR comes in
      if (idleTimeout) clearTimeout(idleTimeout);
    }
  });

  // Decrement count when an XHR finishes successfully
  page.on('requestfinished', request => {
    if (request.resourceType() === 'xhr') {
      activeXhrRequests--;
      checkForIdle(resolve);
    }
  });

  // Handle failed XHRs to avoid hanging indefinitely
  page.on('requestfailed', request => {
    if (request.resourceType() === 'xhr') {
      activeXhrRequests--;
      checkForIdle(resolve);
    }
  });

  // Helper to check if we've reached idle state
  function checkForIdle(resolve) {
    if (activeXhrRequests === 0) {
      // Wait 500ms to confirm no new XHRs are fired (adjust this value as needed)
      idleTimeout = setTimeout(resolve, 500);
    }
  }
});

// Navigate to the page, wait for DOM to load first
await page.goto(url, { waitUntil: 'domcontentloaded' });
// Wait for XHR requests to finish and enter idle state
await xhrIdlePromise;

How this works:

  1. We maintain a counter for active XHR requests. Every time an XHR starts, we increment the count and reset our idle timer to account for new activity.
  2. When an XHR finishes (either successfully or fails), we decrement the count.
  3. Once the count hits 0, we wait a short buffer period (500ms in this example) to ensure no new XHRs are initiated. If nothing new comes in, we resolve the promise—signaling that XHR network idle is reached.

Quick adjustments for your use case:

  • Tweak the idle buffer: If your app fires XHRs in quick succession, increase the 500ms timeout. For more predictable apps, you can lower it.
  • Filter specific XHRs: If you need to ignore polling requests or specific endpoints, add a check for request.url() in the tracking logic to exclude them from the counter.
  • Add a fallback timeout: To avoid hanging if an XHR gets stuck, wrap xhrIdlePromise in Promise.race() with a setTimeout that rejects after a maximum wait time.

内容的提问来源于stack exchange,提问作者Nicholas DiPiazza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:38:24