Можно ли использовать рабочих в скрипте Greasemonkey? - PullRequest
4 голосов
/ 11 октября 2009

Я хотел бы использовать средство Web Worker, представленное в Firefox 3.5, для улучшения скрипта Greasemonkey, над которым я работаю.

Возможно ли это вообще?

Я провел некоторые эксперименты, но не могу обойти проблему загрузки рабочего скрипта из произвольного домена.

Например, это не работает:

var myWorker = new Worker("http://dl.getdropbox.com/u/93604/js/worker.js");

Этот код генерирует сообщение об ошибке в моей консоли Firebug:

Не удалось загрузить скрипт: http://dl.getdropbox.com/u/93604/js/worker.js (nsresult = 0x805303f4)

Очевидно, есть ограничение, которое не позволяет запускать работника с URL-адреса, который не относится к базовому URL-адресу вызывающего скрипта. Вы можете загрузить рабочий скрипт по относительному URL, вот так:

var myWorker = new Worker("worker.js");

Но я не могу получить рабочий сценарий в файловой системе пользователя, чтобы он мог находиться по пути относительно вызывающего сценария.

Я здесь напортачил? Должен ли я отказаться от попыток использовать рабочих в моем скрипте Greasemonkey?

Ответы [ 2 ]

8 голосов
/ 09 сентября 2013

В течение многих лет я думал, что невозможно использовать веб-работников в GM. Конечно, первая идея состояла в том, чтобы использовать URL-адреса данных. Но конструктор Worker, похоже, не принял их.

Сегодня я попробовал еще раз, и сначала он работал без проблем. Только когда я начал использовать функции GM API, конструктор Worker перестал работать.

Кажется, в Firefox есть ошибка, которая не позволяет вам получить доступ к Worker из песочницы с рентгеновским зрением. Даже оценка typeof Worker вызывает исключение. Таким образом, единственный способ использовать рабочих - это получить развернутую версию из развернутого окна:

var echoWorker = new unsafeWindow.Worker("data:text/javascript," +
    "self.onmessage = function(e) {\n" +
    "    self.postMessage(e.data);\n" +
    "};"
);

Конечно, вы должны быть осторожны со специальными персонажами. Лучше кодировать скрипт с помощью base64:

var dataURL = 'data:text/javascript;base64,' + btoa(script);
var worker = unsafeWindow.Worker(dataURL);

В качестве альтернативы вы также можете использовать BLOB-URL:

var blob = new Blob([script], {type: 'text/javascript'});
var blobURL = URL.createObjectURL(blob);
var worker = new unsafeWindow.Worker(blobURL);
URL.revokeObjectURL(blobURL);

Если вы действительно хотите использовать скрипт, размещенный в другом домене, это не проблема, потому что та же политика происхождения не применяется для GM_xmlhttpRequest:

function createWorkerFromExternalURL(url, callback) {
    GM_xmlhttpRequest({
        method: 'GET',
        url: url,
        onload: function(response) {
            var script, dataURL, worker = null;
            if (response.status === 200) {
                script = response.responseText;
                dataURL = 'data:text/javascript;base64,' + btoa(script);
                worker = new unsafeWindow.Worker(dataURL);
            }
            callback(worker);
        },
        onerror: function() {
            callback(null);
        }
    });
}
3 голосов
/ 11 октября 2009
...