Cloudflare 可以检测到我读取响应正文两次吗?

问题描述 投票:0回答:1

我正在构建一个 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,而且我没有看到任何模式

javascript http google-chrome-extension browser cloudflare
1个回答
0
投票

在 Chrome 扩展中拦截 Fetch 请求而不触发 403 错误

使用修补后的

window.fetch
函数拦截请求时,由于 Cloudflare 的机器人检测等机制(标记异常行为),可能会偶尔出现 403 错误。这是解决此问题的优化且可靠的方法。


理解问题

  • 修补了
    fetch
    检测
    :某些服务器,尤其是 Cloudflare 背后的服务器,可以检测修改后的
    window.fetch
    功能并将其归类为类似机器人的行为。
  • 间歇性 403 错误:当服务器的启发式将请求标记为可疑时,可能会触发这些错误。

解决方案:使用Native Fetch,无需直接修改

您可以利用

Service Workers
更谨慎地拦截请求,而不是直接修补 window.fetch。这种方法避免了修改全局对象并降低了被检测的风险。

第 1 步:设置 Service Worker

创建一个 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
      })()
    );
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.