我在标题中所说的仅在chrome中发生,如在Firefox中“((navigator中的'serviceWorker')”)始终为false,并且为“ console.warn(此浏览器不支持Service Worker。');” 触发。
如果您清除浏览器或运行隐身模式,则它最初可以运行,但是当您首次注销然后重新登录时,问题开始。
这是我注册软件的代码:
function activateSW(){
if('serviceWorker' in navigator){
if(window.location.pathname != '/'){
//register with API
if(!navigator.serviceWorker.controller) navigator.serviceWorker.register('/service-worker', { scope: '/' });
//once registration is complete
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration){
//get subscription
serviceWorkerRegistration.pushManager.getSubscription().then(function(subscription){
//enable the user to alter the subscription
$('.js-enable-sub-test').removeAttr("disabled");
//set it to allready subscribed if it is so
if(subscription){
$('.js-enable-sub-test').prop("checked", true);
$('.js-enable-sub-test').parent().addClass('checked');
}
});
});
}
}else{
console.warn('Service workers aren\'t supported in this browser.');
}
}
'/ service-worker'是一个发送到index.php的请求(通过.htaccess)。它最终以以下功能结束:
function serviceworkerJS($params){
$hash = API::request('settings', 'getSWHash', '');
if($hash != false){
setcookie('SW_Hash', $hash, time() + (86400 * 365 * 10), "/");
header('Content-type: text/javascript');
echo "'use strict';
var hash = '".$hash."';";
include(ROOT_PATH.'public/js/service-worker.js');
}elseif(isset($_COOKIE['SW_Hash'])){
header('Content-type: text/javascript');
echo "'use strict';
var hash = '".$_COOKIE['SW_Hash']."';";
include(ROOT_PATH.'public/js/service-worker.js');
}else{
header('HTTP/1.1 404 Not Found');
}
}
在chrome:// serviceworker-internals /中看到的Service-worker.js看起来像这样:(对地址的一些引用已替换为星号)
'use strict';
var hash = 'bd8e78963deebf350f851fbf8cdc5080';
var *****_API_ENDPOINT = 'https://*********.***/';
//For displaying notifications
function showNotification(title, body, icon, data, id) {
var notificationOptions = {
body: body,
icon: icon,
tag: id,
data: data
};
//possibly unnecessary
if(self.registration.showNotification){
return self.registration.showNotification(title, notificationOptions);
}else{
return new Notification(title, notificationOptions);
}
}
//asks the server for messages and sends them for displaying.
function getMessages(event){
//showNotification('debug', 'initial', '', '', 'debug1');
//build question
var FD = new FormData();
FD.append('hash', hash);
//ask start20 for the notifications
event.waitUntil(
fetch(*****_API_ENDPOINT + 'ajax-get-SW-notification/', {method: 'post', body: FD}).then(function(response){
//something went wrong
if (response.status !== 200){
console.log('Error communicating with ******, code: ' + response.status);
showNotification('debug', 'picnic', '', '', 'debug2');
throw new Error();
}
//decode the response
return response.json().then(function(data){
var len = data.notifications.length;
//showNotification('debug', len, '', '', 'propertyName');
//Display
for(var i = 0; i < len -1; i++){
showNotification(data.notifications[i].title,
data.notifications[i].body,
data.notifications[i].imageurl,
data.notifications[i].linkurl,
data.notifications[i].hash);
}
//the last one needs to be returned to complete the promise
return showNotification(data.notifications[len -1].title,
data.notifications[len -1].body,
data.notifications[len -1].imageurl,
data.notifications[len -1].linkurl,
data.notifications[len -1].hash);
});
})
);
}
//when the user installs a new SW
/*self.addEventListener('activate', function(event){
//getMessages(event);
//event.preventDefault();
event.waitUntil(return self.registration.showNotification('bicnic', { body: '*p' }));
});*/
//when the serviceworker gets a puch from the server
self.addEventListener('push', function(event){
getMessages(event);
event.preventDefault();
});
//get the link associated witht he message when a user clicks on it
self.addEventListener('notificationclick', function(event){
//ask if the notification has any link associated with it
var FD = new FormData();
FD.append('hash', event.notification.tag);
//get the link
event.waitUntil(
fetch(******_API_ENDPOINT + 'ajax-notification-has-link/', {method: 'post', body: FD}).then(function(response){
//something went wrong
if (response.status !== 200){
console.log('Error communicating with ********, code: ' + response.status);
return;
}
//decode the response
return response.json().then(function(data){
//if there's a link associated with the message hash
if(data.link){
console.log(******_API_ENDPOINT + 'notification-link/' + event.notification.tag);
return clients.openWindow(*****_API_ENDPOINT + 'notification-link/' + event.notification.tag);
}
});
})
);
});
//unnecessary?
/*self.addEventListener('install', function(event){
//event.preventDefault();
});
self.addEventListener("fetch", function(event) {
});//*/
现在,如果您取消注释“ if(!navigator.serviceWorker.controller)navigator.serviceWorker.register('/ service-worker',{作用域:'/'});” 然后问题消失了,但是服务人员订阅和取消订阅的工作停止了。(if语句似乎并没有做什么用,仅是为了解决这个问题而添加的)
我已经尝试过各种版本的activateSW(),它们具有各种条件,可以运行不同的表达式,并且在不破坏serviceworker的情况下也无法创建一个可以正常工作的版本。我还尝试捕获各个点(注册,帖子)上的错误,但这没有成功,因为它们均未抛出任何错误。
我怀疑可能是因为在您注册服务工作人员时触发了激活事件。现在,如果您抓住了这一点并完成了活动承诺,那么您将无法订阅。但是,我怀疑服务工作者在您注销时仍保持活动状态,这会引起问题。
如果您有疑问或想查看更多代码,请询问。
编辑; 这是解决方案:
self.addEventListener("fetch", function(event) {
event.respondWith(
fetch(event.request)
);
});
您所看到的是在Chrome DevTools的“网络”面板中令人困惑的噪音,但对您的应用程序的行为没有实际影响。
如果服务人员控制页面但不包含fetch
事件处理程序,则当前版本的Chrome(M44稳定版和M46 Canary版)最终会在“网络”面板中以(canceled)
状态记录所有网络请求,如您所见。实际的请求仍然是在没有服务人员干预的情况下发出的,这是第二次成功登录。从您的页面角度来看,事情应该可以按预期进行,但是我完全理解混乱。
我听说有计划使Chrome的Service Worker实施在发出网络请求且没有fetch
事件处理程序时表现得更像“无操作” 。我不知道这些计划能走多远,但是我希望您看到的噪音一旦发生就会消失。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句