SECURITY_ERR: исключение DOM 18 при использовании getImageData в расширении Chrome - PullRequest
10 голосов
/ 01 апреля 2011

Я пишу свое первое расширение для 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 ]

13 голосов
/ 01 апреля 2011

Да, это ограничение безопасности. Как говорится в спецификациях :

Всякий раз, когда вызывается метод toDataURL () элемента холста, для которого флаг origin-clean установлен в false, метод должен вызывать исключение SECURITY_ERR.

Всякий раз, когда метод getImageData () двумерного контекста элемента холста, для которого флаг очистки источника установлен в значение 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;
}
0 голосов
/ 22 августа 2011

Так что я тоже работал над расширением, в котором я хотел использовать данные изображений из междоменных изображений, и обнаружил, что ЭТО ВОЗМОЖНО! (без какой-либо фанки фоновой передачи сообщений на странице)

@ Serg, Оказывается, на веб-страницах вы не можете делать междоменные вещи, однако после некоторого дальнейшего копания я обнаружил, что в расширениях Chrome вы можете!

jistиз этого все, что вам нужно сделать, это запросить разрешения для перекрестного происхождения XMLHttpRequests в вашем манифесте.

{
  "name": "My extension",
  ...
  "permissions": [
    "http://www.google.com/"
  ],
  ...
}

Для получения дополнительной информации (особенно о том, как оставаться в безопасности) прочитайте это .

...