SECURITY_ERR: исключение DOM 18 при использовании getImageData в расширении Chrome
Я пишу свое первое расширение Chrome. Я пытаюсь использовать jQuery и плагин jQuery Image Desaturate, чтобы обесцветить изображение на странице http://www.flickr.com/.
Я загружаю свой скрипт (и jQuery и плагин) программно в моем background.html:
// On browser action click, we load jQuery and the desaturate plugin, then
// call our own flickrnoir.js to desaturate the photo.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, { file: "jquery.js" }, function() {
chrome.tabs.executeScript(null, {file: "jQuery.desaturate.js" }, function() {
chrome.tabs.executeScript(null, { file: "flickrnoir.js" });
})
});
});
Я указал разрешения для страниц Flickr в моем manifest.json
:
"permissions": [
"tabs", "http://www.flickr.com/", "http://*.static.flickr.com/"
]
Кажется, это работает нормально, и я могу, например, перевернуть фон всех div-ов на странице с фото Flickr красным, добавив это в flickrnoir.js
, а затем открыв страницу Flickr и нажав на кнопку моего расширения:
$("div").css("background-color", "#ff0000");
... Итак, я успешно загрузил jQuery, и он может успешно получать доступ и изменять элементы DOM http://*.flickr.com/*
стр.
Однако, когда я пытаюсь использовать плагин desaturate для обесцвечивания изображения (или фактически всех изображений), я сталкиваюсь с ошибкой безопасности. Мой код:
$("img").desaturate();
... в конце концов оказывается в коде плагина jQuery.desaturate, запускающего эту строку:
var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);
В этот момент Chrome создает исключение безопасности:
Uncaught Error: SECURITY_ERR: DOM Exception 18
... и это останавливает меня в моих следах.
РЕДАКТИРОВАТЬ: Хорошо, так что я думаю, это потому, что страница в www.flickr.com
тогда как изображение, которое я копирую на холст, находится в farm6.static.flickr.com
? Это нарушает междоменную политику?
Я действительно еще не знаком с моделью безопасности расширений Chrome или междоменными ограничениями canvas
или как они взаимодействуют, чтобы я мог использовать любую помощь, которую вы можете дать мне в понимании этого, но, конечно, мой фундаментальный вопрос - как мне пройти это исключение безопасности и заставить мой код работать?
2 ответа
Да, это ограничение безопасности. Как сказано в спецификации:
Всякий раз, когда вызывается метод toDataURL() элемента canvas, для которого флаг origin-clean установлен в false, метод должен вызывать исключение SECURITY_ERR.
Всякий раз, когда метод getImageData() 2D-контекста элемента canvas, чей флаг origin-clean установлен в false, вызывается с другими правильными аргументами, метод должен вызывать исключение SECURITY_ERR.
Всякий раз, когда метод measureText() двумерного контекста элемента холста заканчивается использованием шрифта, источник которого отличается от источника документа, которому принадлежит элемент холста, метод должен вызвать исключение SECURITY_ERR.
Когда я работал над похожим расширением, я передал URL-адрес изображения из скрипта контента на фоновую страницу и выполнил все манипуляции с холстами, затем преобразовал холст в URL-адрес данных и отправил его обратно в скрипт контента:
//background.html:
function adjustImage(src, tab) {
var img = new Image();
img.onload = function() {
var canvas = Pixastic.process(img);
chrome.tabs.sendRequest(tab.id, {cmd: "replace", data: canvas.toDataURL()});
};
img.src = src;
}
Поэтому я тоже работал над расширением, в котором я хотел использовать данные изображений из междоменных изображений, и я обнаружил, что ЭТО ВОЗМОЖНО! (без какой-либо фанки фоновой передачи сообщений на странице)
@Serg, как выясняется, на веб-страницах вы не можете делать междоменные вещи, однако, после некоторого дальнейшего копания я обнаружил, что в расширениях Chrome вы можете!
Суть в том, что все, что вам нужно сделать, это запросить разрешения для перекрестного происхождения XMLHttpRequests в вашем манифесте.
{
"name": "My extension",
...
"permissions": [
"http://www.google.com/"
],
...
}
Для получения дополнительной информации (особенно о том, как оставаться в безопасности) прочитайте это.