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

如何检测网页中各请求对应的加载来源脚本?

获取请求的发起来源信息

你提到的Performance API(包括performance.getEntries())确实无法直接提供请求的发起者关联信息,但可以通过以下几种方法实现类似Speedcurve中“loaded by”的功能:

方法一:重写XHR/Fetch方法追踪调用栈

通过拦截页面中所有fetch和XMLHttpRequest的调用,记录请求发起时的调用栈,后续将调用栈信息与Performance API获取的资源条目关联,就能定位到发起请求的脚本。

代码示例:

// 初始化存储请求来源的对象
window.requestSources = window.requestSources || {};

// 重写fetch方法
const originalFetch = window.fetch;
window.fetch = function(...args) {
  const requestUrl = typeof args[0] === 'string' ? args[0] : args[0].url;
  // 记录调用栈
  window.requestSources[requestUrl] = new Error().stack;
  return originalFetch.apply(this, args);
};

// 重写XMLHttpRequest方法
const originalXHR = XMLHttpRequest;
XMLHttpRequest = function() {
  const xhr = new originalXHR();
  const originalOpen = xhr.open;
  xhr.open = function(method, url) {
    window.requestSources[url] = new Error().stack;
    return originalOpen.apply(this, arguments);
  };
  return xhr;
};

// 页面加载完成后关联Performance条目与来源信息
setTimeout(() => {
  performance.getEntriesByType('resource').forEach(entry => {
    const sourceStack = window.requestSources[entry.name];
    console.log(`请求: ${entry.name}`);
    console.log(`发起来源调用栈:\n${sourceStack || '无法追踪(可能为页面初始加载资源)'}`);
  });
}, 5000);

注意:需要在页面加载早期注入这段代码(比如通过Tampermonkey脚本或浏览器扩展),否则会漏掉页面初始阶段的请求。

方法二:使用Chrome DevTools Protocol(CDP)

如果是做自动化性能分析(类似WebPageTest/Speedcurve的场景),可以通过CDP的Network.requestWillBeSent事件获取请求的initiator信息,其中包含发起请求的脚本URL、行号甚至类型(比如script、img、fetch等)。

以Puppeteer为例的代码示例:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  page.on('request', request => {
    const initiator = request.initiator();
    let sourceInfo = '页面本身';
    if (initiator.type === 'script' && initiator.url) {
      sourceInfo = `${initiator.type} - ${initiator.url}:${initiator.lineNumber}`;
    } else if (initiator.type !== 'other') {
      sourceInfo = initiator.type;
    }
    console.log(`请求URL: ${request.url()}`);
    console.log(`Loaded by: ${sourceInfo}`);
    request.continue();
  });

  await page.goto('目标页面URL');
  await browser.close();
})();

这种方法能直接拿到和Speedcurve一致的“loaded by”信息,准确性最高。

方法三:MutationObserver监控动态插入的资源

对于通过DOM动态插入的脚本、图片等资源,可以用MutationObserver监控DOM变化,记录插入这些资源的脚本上下文:

window.scriptSources = window.scriptSources || {};
const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    mutation.addedNodes.forEach(node => {
      if ((node.tagName === 'SCRIPT' || node.tagName === 'IMG') && node.src) {
        window.scriptSources[node.src] = new Error().stack;
      }
    });
  });
});

observer.observe(document, { childList: true, subtree: true });

这种方法仅适用于追踪通过DOM添加的资源,无法覆盖XHR/Fetch发起的请求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:38:24