0

タイトルで述べたことは、Firefox のようにクロムでのみ発生します。代わりにトリガーします。

ブラウザをクリアするか、シークレット モードで実行すると、最初は機能しますが、最初にログアウトしてから再度ログインすると、問題が発生します。

これは、ネットワークログでどのように見えるかです

SWを登録するコードは次のとおりです。

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」は、(.htaccess 経由で) index.php に送信されるリクエストです。最終的には次の関数になります。

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', { scope: '/' });」をコメントアウトすると、その後、問題は消えますが、サービスワーカーのサブスクライブとサブスクライブ解除が機能しなくなります。(if ステートメントはあまり機能していないようで、これを解決するために追加されただけです)

私は、さまざまな式を実行するためのさまざまな条件で activateSW() の多数のバージョンを試しましたが、サービスワーカーを壊さずに機能するバージョンを作成することができませんでした。また、さまざまなポイント(登録、投稿)でエラーをキャッチしようとしましたが、どれもスローしないため、これは失敗しました.

私が問題だと思うのは、サービスワーカーを登録すると、アクティブ化イベントがトリガーされることです。これをキャッチしてイベントの約束を完了すると、サブスクライブできなくなります。ただし、ログアウトしてもサービスワーカーがアクティブなままであり、これが問題を引き起こしていると思われます。

質問がある場合、またはさらにコードを見たい場合は、質問してください。

編集; ここに解決策があります:

self.addEventListener("fetch", function(event) {
    event.respondWith(
        fetch(event.request)
    );
});
4

1 に答える 1

1

Chrome DevTools の [ネットワーク] パネルに紛らわしいノイズが表示されていますが、アプリケーションの動作に実質的な影響はありません。

Service Worker がページを制御しているが、イベント ハンドラーが含まれていないfetch場合、現在のバージョンの Chrome (M44 安定版、および M46 カナリア版) は、ネットワーク パネルにすべてのネットワーク リクエストを(canceled)ステータスとともにログに記録します。実際のリクエストは Service Worker の介入なしで行われます。これは 2 番目の成功したログ エントリです。ページの観点からは期待どおりに動作するはずですが、混乱していることは完全に理解しています。

fetchネットワーク リクエストが行われ、イベント ハンドラがない場合、Chrome の Service Worker 実装を「no-op」のように動作させる計画があると聞いています。これらの計画がどこまで進んでいるのかはわかりませんが、ログに記録されているノイズは、それが実現すれば解消されると思います。

于 2015-08-06T19:49:50.023 に答える