Chrome Manifest V3扩展出现Maximum call stack size exceeded问题求助
Chrome Manifest V3扩展请求追踪栈溢出问题解决
问题场景
开发基于Manifest V3的Chrome学习类扩展,需要追踪站点所有包含https://example子串的请求完整URL,但打开页面时控制台触发Maximum call stack size exceeded错误,同时附带报错信息console.error Unknown server error, msg=Maximum call stack size exceeded, requested_url=/webapi/spa/modules/error404。
原实现代码:
function middlewareRequest(url, options) { if (url && url.includes && url.includes("https://example")) { console.log("URL:", url); } if (window.XMLHttpRequest) { var xhr = new window.XMLHttpRequest(); xhr.open(options.method || "GET", url, true); xhr.send(options.body || null); return xhr; } else { return window.fetch(url, options).then(function (response) { return response; }); } } window.XMLHttpRequest.prototype.open = function () { return middlewareRequest.apply(this, arguments); }; window.fetch = function () { return middlewareRequest.apply(this, arguments); };
错误根源:无限递归
你重写了XMLHttpRequest.prototype.open和window.fetch,但在middlewareRequest内部又创建新的XMLHttpRequest并调用其open方法,或者直接调用window.fetch——而这两个方法已经被替换为middlewareRequest,导致每次调用都会触发新的middlewareRequest调用,形成无限递归,最终引发栈溢出。
此外,原代码逻辑错误:直接在中间件中发起新请求,而非追踪页面原本的请求,这会干扰页面正常逻辑。
修复方案:保存原生方法并拦截放行
先保存原生的请求方法,在拦截逻辑中调用原生方法而非重写后的版本,避免递归;同时仅做URL追踪,不替代页面发起请求。
修复后的代码:
// 提前保存原生请求方法,避免被重写后无法调用 const originalXhrOpen = window.XMLHttpRequest.prototype.open; const originalFetch = window.fetch; // 单独的URL追踪逻辑 function trackTargetUrl(url, options) { if (url && url.includes && url.includes("https://example")) { console.log("追踪到目标URL:", url); } } // 重写XMLHttpRequest的open方法 window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) { // 先追踪URL trackTargetUrl(url, { method }); // 调用原生open方法,保留所有参数 return originalXhrOpen.apply(this, arguments); }; // 重写fetch方法 window.fetch = function(url, options) { // 先追踪URL trackTargetUrl(url, options); // 调用原生fetch方法 return originalFetch.apply(this, arguments); };
关键说明
- 必须先保存原生方法:在重写全局方法前,把原生的
open和fetch存起来,后续在拦截逻辑中调用这个保存的版本,才不会触发递归。 - 不要替代页面请求:原代码中直接创建XHR发送请求的逻辑是错误的,正确的拦截是在页面发起请求时先记录URL,再放行到原生方法,保证页面原有请求流程不受影响。
- 保留所有参数:XMLHttpRequest的
open方法有多个可选参数,要完整传递给原生方法,避免破坏页面的请求配置。
内容的提问来源于stack exchange,提问作者Даниил Ельчуков
相关产品推荐
相关产品推荐

