我正忙着向使用应用脚本托管的网络应用添加网络推送通知。为此,我需要注册一个服务工作者,并且遇到了跨域请求的错误。原始内容由*.googleusercontent.com
托管,而脚本网址为script.google.com/*
。
我能够使用this post成功创建内联工作人员,创建使用脚本从blob
创建的内联网址。现在我陷入了在浏览器中注册工作者的问题。
以下模型有效:
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
错误。
可以安装内联工作人员吗?或者所有已安装的工作人员都必须来自外部脚本吗?
答案 0 :(得分:5)
值得注意的是,与推送通知一起使用的Web Workers和Service Workers是不同的(参见this SO response to read about the difference)。
根据MDN服务工作者require a script 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');
}
}
但与this example(source code here)一样,由于提供网络应用的方式,您会遇到错误:
SecurityError:无法注册ServiceWorker:脚本资源位于重定向后面,不允许这样做。
有一个proposal for Foreign Fetch for Service Workers ,但它仍在草案中。