Как заставить Worker () работать против междоменной области? - PullRequest
3 голосов
/ 11 декабря 2010

Я взломал BeSpin, пытаясь заставить его работать на моем CDN, и я получил кросс-доменный запрос XHR для theme.less, преобразовав его в JSONP.Следующая проблема, с которой я столкнулся, - это новый работник (js_file), где js_file находится в другом домене.

Как / можно ли включить междоменный домен для работника ()?

Могу ли я дать Работнику исходный код напрямую?(т.е. создать очень большой файл JavaScript с другим файлом, встроенным в него) [это не идеально, но должно работать].

Ответы [ 2 ]

2 голосов
/ 24 июня 2011

попробуйте это:

  • создайте функцию с кодом работника
  • получите строковое представление функции (.toString), удалите первую и последнюю строку.Теперь у вас есть строка с рабочим кодом
  • . Создайте новый BlobBuilder (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)
  • добавьте к нему рабочую строку
  • вызовите getBlob (), чтобы получить BLOB-объект
  • , используя URL-адрес окна (window.URL || window.webkitURL), создать URL-адрес объекта, используя createObjectURL
  • , использовать этот URL-адрес для рабочего

Вот код

function getUrlForWorker(workerFunction) {
    var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder,
    URL = window.URL || window.webkitURL,
        mainString = workerFunction.toString(),
        bodyString     = mainString.substring( mainString.indexOf("{")+1, mainString.lastIndexOf("}") ),
        bb = new BlobBuilder()

    bb.append(bodyString)

    return URL.createObjectURL(bb.getBlob())
}
0 голосов
/ 12 августа 2013

Один из способов - создать то, что я называю «Window-Proxy» ....

Скажем, вы хотите разместить работника на cdn, на который вы указываете с помощью new Worker('at.yourCDN.com/worker.js').Этот работник может быть SharedWorker, который позволяет вашим разным вкладкам в ОДНОМ ОДНОМ ДОМЕ поддерживать общее состояние.Возможно, вы хотите, чтобы этот работник был доступен ВСЕМ ТАБЛИЦАМ В РАЗНЫХ ДОМЕНАХ.Другими словами, вы хотели бы использовать работника в качестве платформы службы / сервера.

Проблемы: вы не можете указать на Worker () / SHaredWorker (), который находится в другом домене или использует файлпротокол.

Вот что я буду тестировать на этой неделе:

  1. У вас есть выделенное место для вашего SharedWorker (), например, CDN или из файла: // протокол.
  2. Откройте это местоположение, используя новое окно или iframe.
  3. Сделайте все взаимодействия с этим работником взаимодействующими через это окно или iframe, которые затем пересылают сообщение работнику - это окно / iframeможет быть просто тегом сценария в DOM, который либо тянет работника, либо является встроенным работником.

Подробности: просто выберите любое окно / вкладку, к которому требуется доступ для этого работника, и запустите myWindow.postMessage('my message')и позвольте myWindow запустить port.postMessage(myMsg) для работника.

Как я уже сказал, я еще не проверял это, но надеюсь, что это поможет.

Кроме того, я ищузапущенный безголовый браузер или "Forever Se"rver "с CORS, чтобы, мы надеемся, уменьшить так много iframe-инъекций и window.postMessageing.

Я отправлю обратно, когда найду решение.

************************************ EDIT ************************************

У меняисследовали, как совместно использовать состояние с помощью SharedWorker, не только для нескольких вкладок в одном домене, но также для совместного использования состояния между несколькими доменами - используя SharedWorker как локально размещенную службуЭто не решение, но вот код, демонстрирующий, как создать работника из FileReader API:

// КОД ДОМА:

<b>1</b>
<input id="uploadImage" type="file" name="myPhoto" onchange="onSelect();" autofocus="true" />
<script>
var fReader = new FileReader();
fReader.onload = function(e){
  var blob = new Blob([e.target.result], {type: 'text/javascript'});
  var blobURL = URL.createObjectURL(blob);
  var w = new SharedWorker(blobURL);
  w.port.onmessage = function(e){
    console.log('%%^', e);
  };
  w.port.start();
  w.port.postMessage('Echo');
};
function onSelect(e){
  var file = document.getElementById("uploadImage").files[0];
  var dataURL = fReader.readAsText(file);
}
</script>

// КОД ИЗРАБОЧИЙ ФАЙЛ НА СТОЛБЕ:

var ports = ports || [];
self.onconnect = function(e){
  var port = e.ports[0];
  ports.push(port);

  port.addEventListener('message', function(e){
    port = e.target;
    ports.forEach(function(p){
      p.postMessage('gWorker:: ' + e.data);
    });
  }, false);

  port.start();
};

ВОЗМОЖНЫЕ РЕШЕНИЯ:

Что касается CDN-Worker, кажется, что мы не можем использовать FileReader /BlobBuilder, поскольку они создадут наши собственные worker object в локальном heap.Кажется, мы не можем использовать CORS, так как сервер с включенным CORS может передать рабочий код через XMLHttpRequest, но создание new Worker('http://from.mycors.com/enabled/server') завершается неудачно с тем же "DOM Exception 18" SecurityError, который мы виделислишком много.

Лучшим решением может быть описанный выше метод "Window-Proxy" (iframe.postMessage() для iframe на другом сервере с собственным работником, window.onmessage пересылка сообщения работнику).Обратите внимание, что если вы планируете использовать другой интернет-протокол, отличный от http, window.postMessage использует http.

В качестве альтернативы, некоторые из них прибегают к запуску google-chrome --allow-file-access-from-files - но это очевидно рискованно для производственного сценария.

Другой способ - создать точку встречи для архитектуры WebRTC, которая, возможно, является наиболее надежной.

Надеюсь, это избавит вас от ненужных исследований и поможет найти лучшее решение.

1069 * Ура,
...