webRequest API:如何获取新请求的requestId?

时间:2017-11-16 14:12:46

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

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提供的功能来修改单个请求,但我想确保不会意外修改其他待处理请求。

1 个答案:

答案 0 :(得分:0)

据我所知,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;
}

请注意,无法保证您看到相同的网址,例如,如果针对http://some.domain.test发出请求,您会在收听者中看到http://some.domain.test/(请参阅我的other question了解细节)。或http://可能已由https://取代(此处我不确定,但可能是因为HTTPS Everywhere等其他扩展程序。)

这就是为什么上面的代码只能被看作是这个想法的草图。只要您不对相同的URL启动多个请求,它在实践中似乎工作得很好。不过,我仍然有兴趣了解更好的方法来解决这个问题。