Register inline service worker in web app

半腔热情 提交于 2019-12-11 07:26:43

问题


I'm toying with adding web push notifications to a web app hosted with apps script. To do so, I need to register a service worker and I ran into an error with a cross-domain request. Raw content is hosted from *.googleusercontent.com while the script URL is script.google.com/*.

I was able to successfully create an inline worker using this post on creating inline URLs created from a blob with the script. Now I'm stuck at the point of registering the worker in the browser.

The following model works:

HTML

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

Service Worker

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

  })
</script> 

Inline install

<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); returns a 400: Bad HTTP response code error.

Can inline workers be installed? Or do all installed workers have to come from external scripts?


回答1:


It's worth noting that Web Workers and Service Workers, which are used with push notifications, are different (see this SO response to read about the difference).

According to MDN Service Workers require a script URL. In Google Apps Script you could serve a service worker file with something like:

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');
  }
}

But as in this example (source code here) because of the way web apps are served you'll encounter the error:

SecurityError: Failed to register a ServiceWorker: The script resource is behind a redirect, which is disallowed.

There was a proposal for Foreign Fetch for Service Workers but it's still in draft.



来源:https://stackoverflow.com/questions/47163325/register-inline-service-worker-in-web-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!