Javascript 服务工作者未接收到消息
注意:正在使用CreateReact应用程序模板。。。(修改其中的服务人员) 我正在使用通信通道api向服务工作者发送消息以进行缓存。我使用xmlhttp请求是因为它的ProgressAPI,因为fetch需要一个不确定的加载程序afaik 因此,在收到readystate 4上的数据和状态代码200后,我转到postMessage to SW。我在客户端登录,但在服务人员中没有收到消息 我正在本地开发并使用Chrome扩展来允许本地测试软件和构建: 客户端代码段Javascript 服务工作者未接收到消息,javascript,service-worker,progressive-web-apps,Javascript,Service Worker,Progressive Web Apps,注意:正在使用CreateReact应用程序模板。。。(修改其中的服务人员) 我正在使用通信通道api向服务工作者发送消息以进行缓存。我使用xmlhttp请求是因为它的ProgressAPI,因为fetch需要一个不确定的加载程序afaik 因此,在收到readystate 4上的数据和状态代码200后,我转到postMessage to SW。我在客户端登录,但在服务人员中没有收到消息 我正在本地开发并使用Chrome扩展来允许本地测试软件和构建: 客户端代码段 xhr.onreadysta
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200) {
const res = JSON.parse(this.responseText);
function sendMessage(msg){
console.log("SEND SW MESSAGE");
const msgChan = new MessageChannel();
// This wraps the message posting/response in a promise, which will resolve if the response doesn't
// contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
// controller.postMessage() and set up the onmessage handler independently of a promise, but this is
// a convenient wrapper.
return new Promise(function(resolve, reject){
console.log("Promise Scope");
msgChan.port1.onmessage = function(event){
event.data.error ? reject(event.data.error) : resolve(event.data);
}
// This sends the message data as well as transferring messageChannel.port2 to the service worker.
// The service worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
navigator.serviceWorker.controller.postMessage(msg, [msgChan.port2]);
});
}
sendMessage(res).then(function(){
console.log("SW MESSAGE SENT");
// Storing Quake Data
that.props.setQuakes(res[0]);
// Storing Three Data Obj - SSR Parsing and Creation
that.props.setThreeData(res[1]);
// Greenlight
that.props.setVizInitSuccess(true);
}).catch(function(err){
console.log("Error Caching Data: "+err);
});
} };
服务工作者代码段
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
// Set up a listener for messages posted from the service worker.
// The service worker is set to post a message to all its clients once it's run its activation
// handler and taken control of the page, so you should see this message event fire once.
// You can force it to fire again by visiting this page in an Incognito window.
navigator.serviceWorker.onmessage = function(event) {
console.log("SERVICE WORKER RECIEVED MESSAGE");
console.log(event);
event.ports[0].postMessage("SW Says Hello Back!");
if (event.data.requireData == true && 'caches' in window) {
// Check for cache'd data and load
// clients.matchAll().then(clients => {
// clients.forEach(client => {
// console.log(client);
// //send_message_to_client(client, msg).then(m => console.log("SW Received Message: "+m));
// })
// })
// caches.open('threeData').then(function(cache){
// console.log("SW Cache");
// console.log(cache)
// event.ports[0].postMessage(cache);
// });
} else {
// Cache Data
caches.open('threeData').then(function(cache){
cache.put('/data.json', new Response(event.data.json))
});
}
};
...
服务工作者文件中使用的
navigator
是WorkerNavigator界面,而不是navigator界面
WorkerNavigator是允许从工作者(在本例中是其服务工作者)访问的Navigator接口的子集。
所以navigator
内部服务工作者文件不包含serviceWorker
对象。因此,当您调用navigator.serviceworner.onMessage
时,它会抛出错误
要从客户端接收消息,请使用服务人员文件中的self.addEventListener
self.addEventListener('message', event => {
console.log(`[Message] event: `, event.data);
});
尝试中提到的
self.addEventListener
方法,因此我使用的CreateReact应用程序模板非常有趣。如果我编辑那个服务工作者文件并使用self,它会出错,说不能使用那个变量名,比如它是一个受保护的全局变量或其他什么。但是,如果我从头开始创建一个新文件和一个工作人员,那么我就可以使用它了。实际上,createreact应用程序中的serviceworner.js
实际上不是注册的服务人员。此文件在提供swUrl
的registerValidSW
函数中注册服务工作者。该service worker.js
文件是使用workbox生成的。如果您在chrome开发工具的应用程序选项卡中检查它们<代码>服务人员.js使用Workbox。是的,我必须创建一个不同的服务人员来使用任何self作用域。将registerValidSW中的workbox service worker替换为自定义worker。似乎workbox worker只适用于基本缓存,因为它更难自定义。