พนักงานบริการลงทะเบียนและเปิดใช้งานแล้ว แต่ไม่ทำงานในโหมดออฟไลน์

ในแอปพลิเคชัน UI5 ฉันได้ลงทะเบียนพนักงานบริการใน index.html:

$(document).ready(function() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('service-worker.js', { scope: './' })
      .then(function(registration) {
        console.log("Service Worker Registered");
      })
      .catch(function(err) {
        console.log("Service Worker Failed to Register", err);
      })
  }
});

นอกจากนี้ ฉันยังมีไฟล์ service-worker.js อยู่ในโฟลเดอร์รูท เพื่อให้พนักงานบริการสามารถแคชองค์ประกอบทั้งหมดที่อยู่ด้านล่างได้ ไฟล์นี้มีรหัสต่อไปนี้:

// Set a name for the current cache
var cacheName = 'v2'; 

// Default files to always cache
var cacheFiles = [
    './',
    './inicio.html?I_APLICACION=CAPCGENA02',
    './resources/sap-ui-core.js',
    './resources/sap/ui/core/themes/base/fonts/SAP-icons.ttf',
    './resources/sap-ui-core.js',
    './resources/sap/ui/core/library-preload.js',
    './resources/sap/m/library-preload.js',
    './resources/sap/ui/unified/library-preload.js',
    './resources/sap/ui/comp/library-preload.js',
    './resources/sap/ui/table/library-preload.js',
    './resources/sap/ui/fl/library-preload.js',
    './resources/sap/tnt/library-preload.js',
    './resources/sap/ui/unified/themes/sap_belize/library-parameters.json',
    './resources/sap/ui/table/themes/sap_belize/library-parameters.json',
    './resources/sap/ui/comp/themes/sap_belize/library-parameters.json',
    './resources/sap/tnt/themes/sap_belize/library-parameters.json',
    './resources/sap/ui/layout/library-preload.js',
    './resources/sap/ui/unified/themes/sap_belize/library.css',
    './resources/sap/ui/table/themes/sap_belize/library.css',
    './resources/sap/ui/comp/themes/sap_belize/library.css',
    './resources/sap/tnt/themes/sap_belize/library.css',
    './css/style.css',
    './css/fonts/ttf/CMEEMEN18.ttf',
    './images/temporal/chart.PNG',
    './Component.js',
    './Component-preload.js',
    './manifest.json',
    './api/api.reformation.data.js',
    './api/ApiManager.js',
    './api/ApiStructure.js',
    './api/ibd.api.login.data.js',
    './controller/Home.controller.js',
    './controller/Login.controller.js',
    './controller/Menu.controller.js',
    './controller/fragment/ManagePartes.js',
    './controller/fragment/FilterDialogController.js',
    './controller/structure/Container.controller.js',
    './controller/structur
    './database/apiBBDD.js',
    './database/bbdd.js',
    './i18n/i18n.properties',
    './i18n/i18n_en.properties',
    './i18n/i18n_es.properties',
    './i18n/i18n_en_US.properties',
    './i18n/i18n_es_ES.properties',
    './manager/dataManager/DataManager.js',
    './manager/functionalityManager/FunctionalityManager.js',
    './manager/mappingManager/MappingManager.js',
    './manager/parserManager/ReformationParser.js',
    './manager/sessionManager/SessionManager.js',
    './manager/structureManager/ElementManager.js',
    './manager/structureManager/StructureManager.js',
    './manager/viewManager/ViewManager.js',
    './singleton/Singleton.js',
    './utils/Consts.js',
    './utils/Funcionality.js',
    './utils/FunctionalityEvent.js',
    './utils/MaskedPassword.js',
    './utils/Utils.js',
    './view/Home.view.xml',
    './view/Login.view.xml',
    './view/Menu.view.xml',
    './view/fragment/DialogConfirm.fragment.xml',
    './view/fragment/DialogEnd.fragment.xml',
    './view/fragment/DialogError.fragment.xml',
    './view/fragment/DialogTag.fragment.xml',
    './view/fragment/DialogWaiting.fragment.xml',
    './view/fragment/HistoryDialog.fragment.xml',
    './view/fragment/HistoryNoticeDialog.fragment.xml',

]


self.addEventListener('install', function(e) {
    console.log('[ServiceWorker] Installed');

    // e.waitUntil Delays the event until the Promise is resolved
    e.waitUntil(

        // Open the cache
        caches.open(cacheName).then(function(cache) {

            // Add all the default files to the cache
            console.log('[ServiceWorker] Caching cacheFiles');
            //return cache.addAll(cacheFiles);
            return cache.addAll(cacheFiles.map(url => new Request(url, {credentials: 'same-origin'})));
        })
    ); // end e.waitUntil
});


self.addEventListener('activate', function(e) {
    console.log('[ServiceWorker] Activated');

    e.waitUntil(

        // Get all the cache keys (cacheName)
        caches.keys().then(function(cacheNames) {
            return Promise.all(cacheNames.map(function(thisCacheName) {

                // If a cached item is saved under a previous cacheName
                if (thisCacheName !== cacheName) {

                    // Delete that cached file
                    console.log('[ServiceWorker] Removing Cached Files from Cache - ', thisCacheName);
                    return caches.delete(thisCacheName);
                }
            }));
        })
    ); // end e.waitUntil

});


self.addEventListener('fetch', function(e) {
    console.log('[ServiceWorker] Fetch', e.request.url);

    // e.respondWidth Responds to the fetch event
    e.respondWith(

        // Check in cache for the request being made
        caches.match(e.request)


            .then(function(response) {

                // If the request is in the cache
                if ( response ) {
                    console.log("[ServiceWorker] Found in Cache", e.request.url, response);
                    // Return the cached version
                    return response;
                }

                // If the request is NOT in the cache, fetch and cache

                var requestClone = e.request.clone();
                fetch(requestClone)
                    .then(function(response) {

                        if ( !response ) {
                            console.log("[ServiceWorker] No response from fetch ")
                            return response;
                        }

                        var responseClone = response.clone();

                        //  Open the cache
                        caches.open(cacheName).then(function(cache) {

                            // Put the fetched response in the cache
                            cache.put(e.request, responseClone);
                            console.log('[ServiceWorker] New Data Cached', e.request.url);

                            // Return the response
                            return response;

                        }); // end caches.open

                    })
                    .catch(function(err) {
                        console.log('[ServiceWorker] Error Fetching & Caching New Data', err);
                    });


            }) // end caches.match(e.request)
    ); // end e.respondWith
});

ด้วยทั้งหมดนี้ ฉันจึงได้ติดตั้งและเปิดใช้งานพนักงานบริการอย่างถูกต้อง และถ้าฉันไปที่แท็บ Cache Storage ฉันมีข้อมูลที่แคชไว้:

ที่เก็บข้อมูลแคช

การเชื่อมต่อของฉันปลอดภัย (HTTPS) แต่เมื่อฉันเข้าสู่โหมดออฟไลน์ คำขอจะกลับมาจากแคชดิสก์ แทนที่จะมาจากพนักงานบริการ

ฉันเดาว่าเป็นเพราะมันดึงมาจากแคชอัตโนมัติของเบราว์เซอร์ แต่ถ้าฉันคลิกที่ตัวเลือก "ปิดการใช้งานแคช" ใน Chrome มันจะไม่โหลดหน้าออฟไลน์

ไม่มีใครรู้ว่าทำไมสิ่งนี้ถึงเกิดขึ้น?


person Angel Silvan    schedule 20.02.2018    source แหล่งที่มา
comment
คุณเห็นเครื่องหมาย from service worker เมื่อตรวจสอบ navigator.serviceWorker.controller หรือไม่ ถ้าไม่เช่นนั้น เพจของคุณจะไม่ได้รับการควบคุมโดยพนักงานบริการ แม้ว่า SW ของคุณจะยังคงใช้งานอยู่ คุณต้องตรวจสอบว่าเพจของคุณอยู่ภายใต้ขอบเขตของ SW ใน chrome://serviceworker-internals/ หรือไม่   -  person ashxvi    schedule 20.02.2018
comment
ฉันจะตรวจสอบ navigator.serviceWorker.controller ได้อย่างไร ฉันวางไว้บนคอนโซลจาวาสคริปต์ แต่ส่งคืนค่าว่าง ฉันได้ตรวจสอบขอบเขตใน chrome://serviceworker-internals/ แล้ว และได้ตรวจสอบแล้วว่าเพจของฉันอยู่ภายในขอบเขตของ SW   -  person Angel Silvan    schedule 20.02.2018
comment
โปรดดูตัวอย่างจาก serviceworke.rs/immediate-claim_service-worker_doc.html I คิดว่าคุณต้องเพิ่ม clients.claim() ให้กับ Listener ที่เปิดใช้งานของคุณ เพื่อให้ Service Worker ของคุณพร้อมใช้งานสำหรับเพจที่มีขอบเขตเดียวกัน   -  person ashxvi    schedule 20.02.2018
comment
@AngelSilvan ลดการซิงค์ XHR ตามที่แนะนำใน คำตอบ ด้านล่างหรือไม่   -  person Boghyon Hoffmann    schedule 31.05.2018
comment
ยังไม่ค่อยดีนัก น่าเสียดายที่ฉันไม่สามารถลดการโทรแบบซิงโครนัสทั้งหมดได้   -  person Angel Silvan    schedule 12.06.2018


คำตอบ (1)


นี่คือคำตอบสำหรับ "มีใครเคยทำงานเกี่ยวกับ Service Worker Implementation ใน SAPUI5 บ้างไหม?"
และคำพูดจาก MDN:

[Service Worker] ได้รับการออกแบบให้ ไม่ซิงค์กันอย่างสมบูรณ์; ด้วยเหตุนี้ API เช่น synchronous XHR [...] ไม่สามารถใช้ ภายในพนักงานบริการได้

ดังนั้นในปัจจุบัน Service Worker จะไม่ขัดขวางการซิงค์ XHR และ UI5 ส่ง XHR การซิงค์จำนวนมาก ซึ่งอธิบายว่าทำไม ไฟล์เหล่านั้นไม่ถูกดักจับ

ดังนั้น พยายามลดการซิงค์ XHR ให้มากที่สุดเท่าที่จะเป็นไปได้ อธิบายไว้ที่นี่

  1. สร้างไฟล์ Component-Preload
  2. ตั้งค่าทุกที่ async: true ทุกครั้งที่เป็นไปได้ เช่น.

    • สำหรับส่วนประกอบ

      sap.ui.component({
        manifestUrl: "...",
        async: true,
      })
      
    • Root View (ในตัวอธิบายแอป)

      rootView : {
        viewName: "...",
        type: "XML",
        async: true,
        ...
      },
      
  3. โหลดไลบรารีแบบอะซิงโครนัสผ่านการกำหนดค่าบูตสแตรป preload ด้วยค่า "async" เช่น.:

    data-sap-ui-preload="async"
    
  4. โหลดไลบรารีล่วงหน้าโดยเปิดใช้งาน xx-waitForTheme เช่น.:

    data-sap-ui-libs="sap.m, sap.ui.core, sap.f"
    data-sap-ui-xx-waitForTheme="true"
    

ฉันยังเห็นว่า คุณมีบางส่วน หลีกเลี่ยงการโหลดการควบคุมอย่างเกียจคร้านผ่าน Fragment Factory เนื่องจากแฟรกเมนต์ถูกดึงข้อมูลพร้อมกันด้วยวิธีนี้

person Boghyon Hoffmann    schedule 20.02.2018