首页 > 解决方案 > 如何仅阻止未使用 chrome 扩展缓存的图像?

问题描述

我正在开发一个 chrome 扩展来保存数据,我需要阻止图像。这可以使用 webRequest API 轻松完成,并且可以正常工作。但是现在我想知道我是否可以阻止不在缓存中的图像,因为如果它们是,它不会对数据使用有任何显着差异,而只会对用户看不到那里的图像造成不便。我可以取消阻止缓存的图像吗?

标签: javascriptgoogle-chrome-extension

解决方案


这是一个想法:使用 chrome.webRequest 将所有图像重定向到透明的 1x1 像素,同时通过fetchinonly-if-cached模式检查缓存。如果成功,则恢复内容脚本中的原始 URL。

清单.json:

  • permissions应包含"<all_urls>", "webRequest","webRequestBlocking"
  • 声明内容脚本和后台脚本

background.js(未经测试):

const GIF_1x1 = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';
const FETCH_OPTS = {
  cache: 'only-if-cached',
  mode: 'same-origin',
  method: 'HEAD',
};
const isCached = new Map();
chrome.webRequest.onBeforeRequest.addListener(info => {
  const {url} = info;
  if (!isCached.has(url)) {
    const data = {url, urlHash: '#' + encodeURIComponent(url)};
    fetch(url, FETCH_OPTS).then(() => {
      isCached.set(url, performance.now());
      setTimeout(() => isCached.delete(url), 1000);
      chrome.tabs.sendMessage(info.tabId, {cmd: 'show', data}, {frameId: info.frameId});
    });
    return {redirectUrl: GIF_1x1 + data.urlHash};
  }
}, {
  types: ['image'],
  urls: ['<all_urls>'],
}, ['blocking']);

content.js(未经测试):

chrome.runtime.onMessage.addListener(({cmd, data}) => {
  if (cmd === 'show') {
    for (const el of document.querySelectorAll(`img[src^="data:"][src$="${data.urlHash}"]`)) {
      el.src = data.url;
    }
  }
});

进一步的增强是从缓存相关的 HTTP 标头中计算持续时间,并在 setTimeout 中使用它而不是 1000。


推荐阅读