我正在尝试截取所有标签的屏幕截图并在我的Chrome扩展程序中压缩它们。我的问题在于此错误:代码Unchecked runtime.lastError while running tabs.captureVisibleTab: Failed to capture tab: unknown error at Object.callback
中的chrome.tabs.captureVisibleTab(function(screenshotUrl)
。此错误随意出现。
这是程序代码:
var arr = [];
var i;
var n;
var TAB;
function allScreen(){
var currentTab = TAB[i];
chrome.tabs.update(currentTab.id, {selected: true}, function (){
chrome.tabs.captureVisibleTab(function(screenshotUrl) {
var newImage = new Image();
newImage.src = screenshotUrl;
newImage.onload = function(){
var canvas = document.createElement('canvas');
canvas.width = 400;
canvas.height = 300;
var ctx = canvas.getContext("2d").drawImage(newImage, 0, 0, newImage.width, newImage.height, 0, 0, canvas.width, canvas.height);
var data = canvas.toDataURL('image/jpeg', 1)
arr.push(data);
i++;
if (i < n){allScreen(TAB);}
}
});
});
}
function screenShot(){
arr = [];
chrome.tabs.getAllInWindow(null, function(tabs){
i = 0;
n = tabs.length;
TAB= tabs;
allScreen(tabs, function(){
console.log("finish");
});
});
}
有谁知道问题是什么?
答案 0 :(得分:0)
我在注入的脚本中尝试使用<img src>
将<canvas>
转换为数据URI时出现安全问题 - 我不确定为什么需要将其作为输出chrome.tabs.captureVisibleTab
为already a data URI。
我对传递给allScreen
的参数感到有点困惑,因为他们从来没有从里面引用过 - 而是你要切换到全局变量。
你可以通过承诺轻松实现这一目标。第一个重构allScreen
成为在截屏时解析的承诺:
function screenshotTab(currentTab){
return new Promise((resolve, reject) => {
chrome.tabs.update(currentTab.id, {selected: true}, () => {
if (chrome.runtime.lastError)
// Return as an error for the awaited catch block
reject(`Error selecting tab ${chrome.runtime.lastError}`));
else
chrome.tabs.captureVisibleTab(uri => {
if (chrome.runtime.lastError)
reject(`Error getting screenshot ${chrome.runtime.lastError}`));
else
resolve(uri);
});
});
});
}
另一个承诺可以给我们提供标签:
function getTabsInWindow() {
return new Promise((resolve, reject) => {
chrome.tabs.getAllInWindow(null, tabs => {
if (chrome.runtime.lastError)
reject(`Error getting tabs in window ${chrome.runtime.lastError}`));
else
resolve(tabs);
});
});
}
然后我们可以使用map
将其应用于所有标签:
async function screenShotAll() {
// We can use await to get the result of the promise
const tabs = await getTabsInWindow();
// map the collection of tabs into promises waiting for screenshots
const runningScreenshots = tabs.map(screenshotTab);
// Use await with Promise.all to wait for them all to call back
const result = await Promise.all(runningScreenshots);
console.log('done', result);
return result;
}
此函数现在返回一个promise,因此您可以执行以下操作:
// async-await syntax
const finalResult = await screenShotAll();
// Or promise syntax works too
screenShotAll().then(finalResult => { /* deal with result */ });
最后,您可以使用库(例如chrome-extension-async
)创建所有promise包装器并chrome.runtime.lastError
检查。