运行tabs.captureVisibleTab时未经检查的runtime.lastError:无法捕获选项卡:未知错误

时间:2017-04-26 05:14:37

标签: javascript google-chrome-extension

我正在尝试截取所有标签的屏幕截图并在我的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");
        });
    });
}

有谁知道问题是什么?

1 个答案:

答案 0 :(得分:0)

我在注入的脚本中尝试使用<img src><canvas>转换为数据URI时出现安全问题 - 我不确定为什么需要将其作为输出chrome.tabs.captureVisibleTabalready 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检查。