Chrome扩展程序 - 无法在'CanvasRenderingContext2D'上执行'getImageData':画布已被跨源数据污染

时间:2015-04-29 09:22:10

标签: javascript canvas google-chrome-extension allow-same-origin

我正在尝试在Chrome扩展程序上实现一些JS库,扫描包含裸露的所有图像。无论如何,通过尝试为每个图像读取画布的上下文来做到这一点,我在下面有例外。这将发生在每一页上。我不明白为什么我有这个例外,我应该如何处理/避免它。

script.js:33

的例外情况
Uncaught SecurityError: Failed to execute 'getImageData' on 
'CanvasRenderingContext2D': The canvas has been tainted by cross-origin

的script.js

$(window).load(function() {
    console.log('NudityBlocker -- Loaded');
    $('img:visible').each(function() {
        var uniqueId = guid();
        var thisImage = $(this);
        thisImage.css('visibility', 'hidden');
        thisImage.attr('data-nudejs-id', uniqueId);
        setTimeout(scan(thisImage), 0);
    });
    console.log('NudityBlocker -- Finished scanning');
});

function scan(image) {
    // Create necessary elements
    var nudeJsId = image.attr('data-nudejs-id');
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext('2d');

    // Draw image on canvas
    canvas.width = image[0].width;
    canvas.height = image[0].height;
    ctx.drawImage(image[0], 0, 0);

    // Get image date and create scanner worker
    var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
    var myWorker = new Worker(nudeUrl);
    var message = [imageData, canvas.width, canvas.height];
    myWorker.postMessage(message);
    myWorker.onmessage = function(event){
        var imageObj = $('[data-nudejs-id=' + nudeJsId + ']');
        if(event.data){ 
            // It's nude
            var width = imageObj.width();
            var height = imageObj.height();
            imageObj.attr('src', chrome.extension.getURL('assets/images/blocked.png')).width(width).height(height);
        }
        // Display images again either original or with blocked sign
        imageObj.css('visibility', 'visible');
    }
}

// Generate GUID's
function guid() {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
    }
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}

background.js

function executeScripts(tabId) {
    console.log('NudityBlocker -- ExecuteScripts()');
    chrome.tabs.executeScript(tabId, {file: "assets/js/jquery.min.js"}, function() {
        chrome.tabs.executeScript(tabId, {file: "assets/js/nudejs.min.js"});
        chrome.tabs.executeScript(tabId, {file: "assets/js/script.js"});
    });
}

var onComplete = function (details) { 
    executeScripts(details.tabId); 
}

var onUpdate = function (tabId) { 
    executeScripts(tabId); 
}

function updateIcons() {
    console.log('NudityBlocker -- updateIcons()');
    chrome.storage.sync.get(['nudityBlockerStatus'], function(items) {
        status = items.nudityBlockerStatus;
        console.log('NudityBlocker -- updateIcons() - Status: ' + status);
        if(status === 'enabled') {
            chrome.browserAction.setIcon({path: "assets/icon/icon48a.png"});
        }
        else if(status === 'disabled') {
            chrome.browserAction.setIcon({path: "assets/icon/icon48d.png"});
        }
    });
}

function updateStatus(status) {
    console.log('NudityBlocker -- UpdateStatus()');
    console.log('NudityBlocker -- UpdateStatus() - Status: ' + status);
    var result;
    if (status === 'enabled') {
        result = "disabled";
        chrome.storage.sync.set({'nudityBlockerStatus' : result});
        chrome.tabs.onUpdated.removeListener(onUpdate);
        chrome.webNavigation.onCompleted.removeListener(onComplete);
    }
    else if (status === 'disabled') {
        result = "enabled";
        chrome.storage.sync.set({'nudityBlockerStatus' : result});
        addListeners();
    }
    updateIcons();
    return result;
}

function addListeners() {
    console.log('NudityBlocker -- AddListeners()');
    chrome.tabs.onUpdated.addListener(onUpdate);
    chrome.webNavigation.onCompleted.addListener(onComplete);
}

function initialize() {
    console.log('NudityBlocker -- Initialize()');
    chrome.storage.sync.set({'nudityBlockerStatus' : 'enabled'});
    console.log('NudityBlocker -- Initialize() - Status: ' + status);
    updateIcons();
    addListeners();
}

// Add event listeners
chrome.runtime.onInstalled.addListener(initialize());

P.S。我在StackOverflow中找到的最类似问题如下:

Canvas has been tainted by cross-origin data via local chrome:// extension URL

但这不是重复,我也没有完全理解答案。

0 个答案:

没有答案