3

我正在尝试将网络推送通知添加到使用应用程序脚本托管的网络应用程序中。为此,我需要注册一个服务工作者,但我遇到了一个跨域请求错误。原始内容托管*.googleusercontent.com在脚本 URL 为script.google.com/*.

我能够使用这篇关于创建blob使用脚本创建的内联 URL 的帖子成功地创建内联工作者。现在我被困在浏览器中注册工作人员的地方。

以下模型有效:

HTML

<!-- Display the worker status -->
<div id="log"></log>

服务工作者

<script id="worker" type="javascript/worker">
  self.onmessage = function(e) {
    self.postMessage('msg from worker');
  };
  console.log('[Service Worker] Process started');

  })
</script> 

内联安装

<script>
  function log(msg) {
    var fragment = document.createDocumentFragment();
    fragment.appendChild(document.createTextNode(msg));
    fragment.appendChild(document.createElement('br'));

    document.querySelector("#log").appendChild(fragment);
  }

  // Create the object with the script
  var blob = new Blob([ document.querySelector("#worker").textContent ]);

  // assign a absolute URL to the obejct for hosting
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    log("Received: " + e.data);
  }

  worker.postMessage('start');
  // navigator.serviceWorker.register(worker) this line fails
</script>

navigator.serviceWorker.register(worker);返回400: Bad HTTP response code错误。

可以安装 inline worker 吗?还是所有已安装的工作人员都必须来自外部脚本?

4

1 回答 1

7

值得注意的是,与推送通知一起使用的 Web Worker 和 Service Worker 是不同的(请参阅此 SO 响应以了解差异)。

根据 MDN Service Workers需要一个脚本 URL。在 Google Apps 脚本中,您可以使用以下内容提供服务工作人员文件:

function doGet(e) {
  var file = e.parameter.file;
  if (file == 'service-worker.js'){
    return ContentService.createTextOutput(HtmlService.createHtmlOutputFromFile('service-worker.js').getContent())
                         .setMimeType(ContentService.MimeType.JAVASCRIPT);
  } else {
    return HtmlService.createHtmlOutputFromFile('index');
  }
}

但是在这个例子这里的源代码)中,由于 web 应用程序的服务方式,你会遇到错误:

SecurityError:无法注册 ServiceWorker:脚本资源位于重定向后面,这是不允许的。

有一个针对 Service Workers 的 Foreign Fetch 的提案,但它仍在草稿中。

于 2017-11-07T21:46:08.097 回答