我正在构建一个 Chrome 扩展程序。我需要拦截对特定端点的请求以获取响应正文并在扩展中使用响应(一切正常,没有恶意软件)
为此,我用代码覆盖
window.fetch
函数:
const originalFetch = window.fetch;
window.fetch = async function (...args) {
const response = await originalFetch(...args);
const request = args[0];
const url = request instanceof Request ? request.url : request instanceof URL ? request.href : request;
if (url.includes('api/search')) {
const data = await response.clone().json();
if (data.myInfo) {
window.dispatchEvent(
new CustomEvent('OnMyInfoLoaded', {
detail: {
myInfo: data.myInfo,
},
}),
);
}
}
return response;
};
此脚本被注入到清单中:
{
"matches": [
"https://external-website.com/*/*"
],
"js": [
"dist/injectCustomFetch.bundle.js"
],
"run_at": "document_start"
}
在 99% 的情况下,对
search
的请求有效并且我得到了数据,但有时我从服务器得到 403 forbidden
。服务器使用 cloudflare,所以我假设 cloudflare 以某种方式检测到 fetch
已修补?我无法访问服务器日志/cloudflare 日志,因为我不是服务器的所有者
这个错误也很难发现,因为大多数时候它都工作正常,偶尔会出现 403,而且我没有看到任何模式
使用修补后的
window.fetch
函数拦截请求时,由于 Cloudflare 的机器人检测等机制(标记异常行为),可能会偶尔出现 403 错误。这是解决此问题的优化且可靠的方法。
fetch
检测:某些服务器,尤其是 Cloudflare 背后的服务器,可以检测修改后的 window.fetch
功能并将其归类为类似机器人的行为。您可以利用
Service Workers更谨慎地拦截请求,而不是直接修补
window.fetch
。这种方法避免了修改全局对象并降低了被检测的风险。
创建一个 Service Worker 来拦截网络请求。这允许您监视和修改请求和响应。
// serviceWorker.js
self.addEventListener('fetch', async (event) => {
const url = new URL(event.request.url);
// Check if the request matches the endpoint you want to intercept
if (url.pathname.includes('/api/search')) {
event.respondWith(
(async () => {
const response = await fetch(event.request);
// Clone and parse the response
const clonedResponse = response.clone();
const data = await clonedResponse.json();
// Dispatch a custom event to share the intercepted data
if (data.myInfo) {
self.clients.matchAll().then((clients) => {
clients.forEach((client) => {
client.postMessage({
type: 'OnMyInfoLoaded',
detail: { myInfo: data.myInfo },
});
});
});
}
return response; // Return the original response
})()
);
}
});