我去过的网站上有旧页面很有用,但图片已经在他们的网站上消失了。幸运的是,对于我,我碰巧有一堆这些图片,因为我保留了它们的副本。因此,我可以轻松地逐一查看这些图像。但是,这就是我想要做的事情:
我想写一个Chrome扩展程序,它会以某种方式找到任何无法加载的图片,并将其替换为我将在扩展程序中打包的图片。
所以,比如说,如果原始图片是http://broken.site/whatever1/whatever2/whatever3/missing.jpg
(如果它确实是错误的),我希望将其替换为我在扩展程序中的missing.jpg
我 希望它从我提供的缓存中加载来自该网站的所有图像,只有那些错误。有一个简单的方法吗?
我可以看到如何用这个来获取所有图像:
imgs = document.getElementsByTagName("img")
imgs[0].src
似乎给了我一个网址,这很酷。但imgs[0].complete
表示完整,无论是否成功检索到图像。有没有办法弄清楚特定图像是否确实加载了?
答案 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"]