Chrome扩展程序可修改无法加载的图像

时间:2015-01-23 09:44:07

标签: javascript google-chrome google-chrome-extension

我去过的网站上有旧页面很有用,但图片已经在他们的网站上消失了。幸运的是,对于,我碰巧有一堆这些图片,因为我保留了它们的副本。因此,我可以轻松地逐一查看这些图像。但是,这就是我想要做的事情:

我想写一个Chrome扩展程序,它会以某种方式找到任何无法加载的图片,并将其替换为我将在扩展程序中打包的图片。

所以,比如说,如果原始图片是http://broken.site/whatever1/whatever2/whatever3/missing.jpg(如果它确实是错误的),我希望将其替换为我在扩展程序中的missing.jpg

希望它从我提供的缓存中加载来自该网站的所有图像,只有那些错误。有一个简单的方法吗?

我可以看到如何用这个来获取所有图像:

imgs = document.getElementsByTagName("img")

imgs[0].src似乎给了我一个网址,这很酷。但imgs[0].complete表示完整,无论是否成功检索到图像。有没有办法弄清楚特定图像是否确实加载了?

2 个答案:

答案 0 :(得分:2)

您可以使用webRequest API捕获并重定向服务器使用404回复的请求。

这样,您可以在后台脚本中执行此操作,并且不需要使用内容脚本来分析包含document.getElementsByTagName("img")的页面,请求将在“飞行中”被截获。

function isMissing(line) {
  return !!(line.match(/^[^ ]* 404/));
}

chrome.webRequest.onHeadersReceived.addListener(
  function(details) {
    if(isMissing(details.statusLine)) {
      var fixedURL;
      /* TODO: Assign fixedURL based on details.url */
      // If the image is in the extension, use
      //   chrome.runtime.getURL("filename.jpg")
      return {redirectUrl: fixedURL};
    }
  },
  {
    // Tailor this filter for your site
    urls: ["*://*.example.com/*"],
    types: ["image"]
  },
  ["blocking"]
);

您需要主机权限(例如"*://*.example.com/*"),"webRequest""webRequestBlocking"

答案 1 :(得分:1)

我构建了扩展程序Image Fallback,这听起来非常类似于您要实现的目标。

您可以在github上查看扩展程序的源代码。我在下面的代码库中添加了几个相关的代码段。

以下是后台脚本中的代码,用于侦听无法加载的图像。然后它会向内容脚本发送一条消息,其中包含需要替换的图像。

/**
 * Stores messages for each tab keyed by tabId
 *
 * These will be used if an image errors before the content script has loaded 
 */
var tabMessages = {};

/**
 * Listen to all responses for images
 * 
 * If the status code is 404 and the host have a fallback url configured notify the content script
 */
chrome.webRequest.onCompleted.addListener(function(e) {

  // Ignore responses if the status code was not a 404 or 500 
  if (!e.statusCode || (e.statusCode !== 404 && e.statusCode !== 500)) {
    return;
  }

  var message = {
    target: targetImage,
    fallback: fallbackUrl
  };

  // Send a message to the content script for this tab
  chrome.tabs.sendMessage(e.tabId, message, function(response) {
    if (typeof response === 'undefined') {
      // The content script probably hasn't loaded yet
      // Add fallback to the message queue for this tab
      // Instead the content script must request image replacements once it is loaded
      tabMessages[e.tabId].push(message);
    }
  });
}, {
  urls: ['<all_urls>'],
  types: ['image']
}, ['responseHeaders']);

这是内容脚本,用于侦听来自后台脚本的消息,然后交换图像。

/**
 * Request any images that have errored before this script was loaded from the background script.
 */
chrome.runtime.sendMessage({
  action: 'getImageFallbacks'
}, function(response) {
  if (!response || !response.length) {
    return;
  }

  response.forEach(function(replace) {

    // Replace the images with your fallback
    $('[src$="'+ replace.target +'"]').attr('src', replace.fallback);

  });
});

/**
 * Listen for image replacement requests sent from the background script
 */
chrome.runtime.onMessage.addListener(function(replace, sender, sendResponse) {

  // Replace the images with your fallback
  $('[src$="'+ replace.target +'"]').attr('src', replace.fallback);

  // Send a response to the background script so it knows we have replaced this image
  sendResponse({
    success: true
  });
});

您还需要在manifest.json中获得以下权限:

"permissions": ["<all_urls>", "webRequest","webRequestBlocking", "tabs", "storage"]