Подтвердить что ты не робот

Как загрузить общий веб-рабочий с помощью пользователя 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-адрес файла).

Если будет сказано, если мой вопрос может быть каким-то образом улучшен или уточнен, пожалуйста, оставьте комментарий.

4b9b3361

Ответ 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