【问题标题】:webRequest API: How to get the requestId of a new request?webRequest API:如何获取新请求的 requestId?
【发布时间】:2017-11-18 01:19:59
【问题描述】:

chrome.webRequest API 有请求 ID 的概念(来源:Chrome webRequest documention):

请求 ID

每个请求都由一个请求 ID 标识。此 ID 在浏览器会话和扩展上下文中是唯一的。它在请求的生命周期内保持不变,可用于匹配同一请求的事件。请注意,在 HTTP 重定向或 HTTP 身份验证的情况下,多个 HTTP 请求会映射到一个 Web 请求。

即使跨重定向,您也可以使用它来关联请求。但是,当使用 fetchXMLHttpRequest 开始新请求时,您最初如何阻止 id?

到目前为止,我还没有找到比使用请求的 URL 作为在新请求和 requestId 之间建立初始链接更好的方法。但是,如果对同一资源有重叠的请求,这是不可靠的。

问题:

  • 如果您提出新请求(使用fetchXMLHttpRequest),您如何可靠地访问requestId?
  • fetch API 或 XMLHttpRequest API 是否允许访问 requestId?

我想做的是使用 webRequest API 提供的功能来修改单个请求,但我想确保我不会意外修改其他待处理的请求。

【问题讨论】:

  • request event callbacks处进一步阅读文档,它被传递到回调中
  • @PatrickEvans 我可以安装一个 onBeforeRequest 监听器并从那里获取请求 id 并立即删除监听器。尽管如此,它仍会被延迟调用。据我了解,不能保证它首先触发时来自请求。可以肯定的是,我也只检查 URL 是否匹配。然后,我想假设我们得到了正确的 requestId 是相当安全的。
  • 同样匹配 URL 也不是很简单。例如,可以添加尾部斜杠。

标签: javascript google-chrome-extension xmlhttprequest fetch-api firefox-addon-webextensions


【解决方案1】:

据我所知,fetchXHMLHttpRequest API 没有直接支持。另外,我不知道获取 requestId 的完全可靠的方法。

我最终做的是安装一个onBeforeRequest 侦听器,存储 requestId,然后立即再次删除该侦听器。例如,它可能看起来像这样:

function makeSomeRequest(url) {

  let listener;
  const removeListener = () => {
    if (listener) {
      chrome.webRequest.onBeforeRequest.removeListener(listener);
      listener = null;
    }
  };

  let requestId;
  listener = (details) => {
    if (!requestId && urlMatches(details.url, url)) {
      requestId = details.requestId;
      removeListener();
    }
  };
  chrome.webRequest.onBeforeRequest.addListener(listener, { urls: ['<all_urls>'] });

  // install other listeners, which can then use the stored "requestId"
  // ...

  // finally, start the actual request, for instance
  const promise = fetch(url).then(doSomething);

  // and make sure to always clean up the listener
  promise.then(removeListener, removeLister);
}

它并不完美,匹配 URL 是我未解决的一个细节。您可以简单地比较details.url 是否与url 相同:

function urlMatches(url1, url2) {
  return url1 === url2;
}

请注意,不能保证您看到相同的 URL,例如,如果向 http://some.domain.test 发出请求,您将在侦听器中看到 http://some.domain.test/(有关详细信息,请参阅我的 other question)。或者 http:// 可能已经被 https:// 替换(这里我不确定,但可能是因为其他扩展,如 HTTPS Everywhere)。

这就是为什么上面的代码只能被看作是这个想法的草图。只要您不对同一个 URL 发起多个请求,它在实践中似乎就足够好用了。尽管如此,我还是有兴趣了解解决问题的更好方法。

【讨论】:

    猜你喜欢
    • 2019-01-26
    • 2023-03-31
    • 2020-01-17
    • 2020-10-26
    • 2016-03-16
    • 1970-01-01
    • 2019-05-27
    • 2014-06-29
    • 1970-01-01
    相关资源
    最近更新 更多