Как загрузить общий веб-рабочий с помощью пользователя script?
Я хочу загрузить общего пользователя с пользователем script. Проблема в том, что пользователь-script является бесплатным и не имеет бизнес-модели для размещения файла - и я не хочу использовать сервер, даже свободный, для размещения одного крошечного файла. Независимо от того, Я попробовал это, и я (конечно) получаю ту же ошибку исходной политики:
Uncaught SecurityError: Failed to construct 'SharedWorker': Script at
'https://cdn.rawgit.com/viziionary/Nacho-Bot/master/webworker.js'
cannot be accessed from origin 'http://stackoverflow.com'.
Другой способ загрузить веб-пользователя, преобразовывая рабочую функцию в строку, а затем в Blob и загружая ее как рабочий, но я тоже это пробовал:
var sharedWorkers = {};
var startSharedWorker = function(workerFunc){
var funcString = workerFunc.toString();
var index = funcString.indexOf('{');
var funcStringClean = funcString.substring(index + 1, funcString.length - 1);
var blob = new Blob([funcStringClean], { type: "text/javascript" });
sharedWorkers.google = new SharedWorker(window.URL.createObjectURL(blob));
sharedWorkers.google.port.start();
};
И это тоже не работает. Зачем? Поскольку общие пользователи делятся на основе местоположения, из которого загружен их рабочий файл. Поскольку createObjectURL
генерирует уникальное имя файла для каждого использования, у рабочих никогда не будет одинакового URL-адреса и поэтому он никогда не будет использоваться.
Как я могу решить эту проблему?
Примечание: Я пробовал спрашивать о конкретных решениях, но на данный момент я думаю лучшее, что я могу сделать, это попросить более широкую решение проблемы, так как все мои попытки принципиально невозможно из-за той же политики происхождения или способа URL.createObjectURL
работает (из спецификаций, кажется невозможным изменить полученный URL-адрес файла).
Если будет сказано, если мой вопрос может быть каким-то образом улучшен или уточнен, пожалуйста, оставьте комментарий.
Ответы
Ответ 1
Вы можете использовать fetch()
, response.blob()
для создания Blob URL
типа application/javascript
из возвращенного Blob
; установите SharedWorker()
параметр Blob URL
, созданный URL.createObjectURL()
; используйте window.open()
, load
событие только что открытого window
для определения того же SharedWorker
, ранее определенного в оригинале window
, прикрепите событие message
к исходному SharedWorker
при вновь открывшемся window
s.
javascript
был проверен на console
на Как очистить содержимое iFrame от другого iFrame, где текущий URL-адрес вопроса должен быть загружен в новый tab
с message
от открытия window
через worker.port.postMessage()
обработчик событий, зарегистрированный в console
.
Открытие window
также должно регистрироваться при событии message
при открытии window
с помощью worker.postMessage(/* message */)
, аналогично при открытии window
window.worker = void 0, window.so = void 0;
fetch("https://cdn.rawgit.com/viziionary/Nacho-Bot/master/webworker.js")
.then(response => response.blob())
.then(script => {
console.log(script);
var url = URL.createObjectURL(script);
window.worker = new SharedWorker(url);
console.log(worker);
worker.port.addEventListener("message", (e) => console.log(e.data));
worker.port.start();
window.so = window.open("https://stackoverflow.com/questions/"
+ "38810002/"
+ "how-can-i-load-a-shared-web-worker-"
+ "with-a-user-script", "_blank");
so.addEventListener("load", () => {
so.worker = worker;
so.console.log(so.worker);
so.worker.port.addEventListener("message", (e) => so.console.log(e.data));
so.worker.port.start();
so.worker.port.postMessage("hi from " + so.location.href);
});
so.addEventListener("load", () => {
worker.port.postMessage("hello from " + location.href)
})
});
В console
на любом tab
вы можете использовать, например; в Как очистить содержимое iFrame от другого iFrame worker.postMessage("hello, again")
в новом window
текущего URL Как я могу загрузите совместно используемого веб-рабочего с пользователем script?, worker.port.postMessage("hi, again");
, где message
события, прикрепленные к каждому window
, связь между двумя window
может быть достигнута с использованием оригинала SharedWorker
, созданного на начальный URL.
Ответ 2
Предпосылка
- Как вы уже исследовали и как уже упоминалось в комментариях,
SharedWorker
URL-адрес подчиняется той же политике происхождения.
- В соответствии с этим вопросом нет поддержки CORS для
Worker
URL.
- Согласно эта проблема
GM_worker
теперь поддержка WONT_FIX и
кажется достаточно близким к невозможному для реализации из-за изменений в Firefox.
Там также примечание, в котором песочница Worker
(в отличие от
unsafeWindow.Worker
) тоже не работает.
Дизайн
Предполагаю, что вы хотите достичь - это тег @include *
, который будет собирать некоторые статистические данные или создавать глобальный пользовательский интерфейс, который будет отображаться повсюду. И, таким образом, вы хотите, чтобы работник поддерживал некоторые штатные или статистические агрегаты во время выполнения (что будет легко получить доступ из каждого экземпляра user- script) и/или вы хотите выполнить некоторую процедуру вычисления (например, иначе) это замедлит целевые сайты).
На пути любого решения
Решение, которое я хочу предложить, заключается в замене SharedWorker
на альтернативу.
- Если вы хотите просто сохранить состояние совместно используемого рабочего, просто используйте хранилище Greasemonkey (
GM_setValue
и друзья). Он был распространен среди всех экземпляров userscript (SQLite соответствует сценам).
- Если вы хотите сделать что-то сложное для вычисления, ему в
unsafeWindow.Worker
и вернуть результат в хранилище Greasemonkey.
- Если вы хотите сделать несколько фоновых вычислений, и он должен запускаться только одним экземпляром, существует множество библиотек синхронизации между окнами (в основном они используют
localStorage
, но Greasemomkey имеет тот же API, поэтому он должен "t трудно записать адаптер к нему). Таким образом, вы можете приобрести блокировку в одном экземпляре usercript и запустить в нем свои подпрограммы. Например, IWC или ByTheWay (вероятно, используется здесь в Stack Exchange, сообщить об этом).
Другой способ
Я не уверен, но может быть какое-то гениальное отталкивание ответов, сделанное из ServiceWorker
, чтобы сделать SharedWorker
работать так, как вам хотелось бы. Отправная точка находится в этом ответе на редактирование.
Ответ 3
Я уверен, что вы хотите получить другой ответ, но, к сожалению, это то, к чему это сводится.
Браузеры реализуют политики одного и того же происхождения для защиты интернет-пользователей, и хотя ваши намерения чисты, никакой законный браузер не позволяет вам изменить происхождение sharedWorker.
Все контексты просмотра в sharedWorker
должны делиться тем же самым происхождением
Вы не можете взломать эту проблему, я пытаюсь использовать iframes в дополнение к вашим методам, но не будет работать.
Возможно, вы можете поместить файл javascript в github и использовать их службу raw.
для получения файла, таким образом вы можете запустить его без особых усилий.
Update
Я читал хром-обновления, и я вспомнил, что вы спрашиваете об этом.
Сотрудники службы перекрестного происхождения прибыли на хром!
Чтобы сделать это, добавьте следующее в событие установки для SW:
self.addEventListener('install', event => {
event.registerForeignFetch({
scopes: [self.registration.scope], // or some sub-scope
origins: ['*'] // or ['https://example.com']
});
});
Некоторые другие соображения также необходимы, проверьте:
Полная ссылка: https://developers.google.com/web/updates/2016/09/foreign-fetch?hl=en?utm_campaign=devshow_series_crossoriginserviceworkers_092316&utm_source=gdev&utm_medium=yt-desc