Pekerja layanan dapat mencegat permintaan jaringan untuk halaman. Layanan ini dapat merespons browser dengan konten yang di-cache, konten dari jaringan, atau konten yang dihasilkan dalam pekerja layanan.
workbox-routing
adalah modul yang memudahkan untuk "mengarahkan" permintaan ini ke
berbagai fungsi yang memberikan respons.
Bagaimana {i>Routing<i} Dilakukan
Jika permintaan jaringan menyebabkan peristiwa pengambilan pekerja layanan, workbox-routing
akan mencoba merespons permintaan menggunakan rute dan pengendali yang disediakan.
Hal-hal yang perlu diperhatikan dari penjelasan di atas adalah:
Metode permintaan adalah hal penting. Secara default, Rute didaftarkan untuk permintaan
GET
. Jika ingin mencegat jenis permintaan lain, Anda harus menentukan metodenya.Urutan pendaftaran Rute adalah hal yang penting. Jika beberapa Rute terdaftar yang dapat menangani permintaan, Rute yang didaftarkan pertama akan digunakan untuk merespons permintaan tersebut.
Ada beberapa cara untuk mendaftarkan rute: Anda dapat menggunakan callback, ekspresi reguler, atau instance Rute.
Pencocokan dan Penanganan di Rute
"Rute" di kotak kerja tidak lebih dari dua fungsi: fungsi "pencocokan" untuk menentukan apakah rute harus cocok dengan permintaan dan fungsi "penanganan", yang harus menangani permintaan dan merespons dengan respons.
Workbox dilengkapi dengan beberapa helper yang akan melakukan pencocokan dan penanganan untuk Anda, tetapi jika Anda menginginkan perilaku yang berbeda, menulis pencocokan kustom dan fungsi pengendali adalah opsi terbaik.
Fungsi callback pencocokan mendapatkan ExtendableEvent
, Request
, dan objek URL
yang dapat Anda cocokkan dengan menampilkan nilai tepercaya. Contoh sederhana, Anda dapat mencocokkan
URL tertentu seperti:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
Sebagian besar kasus penggunaan dapat dicakup dengan memeriksa / menguji url
atau
request
.
Fungsi callback pengendali akan diberi objek ExtendableEvent
, Request
, dan URL
yang sama beserta nilai params
, yang merupakan nilai yang ditampilkan oleh fungsi "match".
const handlerCb = async ({url, request, event, params}) => {
const response = await fetch(request);
const responseBody = await response.text();
return new Response(`${responseBody} <!-- Look Ma. Added Content. -->`, {
headers: response.headers,
});
};
Pengendali Anda harus menampilkan promise yang di-resolve ke Response
. Dalam contoh ini, kami menggunakan async
dan await
.
Di balik layar, nilai Response
yang ditampilkan akan digabungkan dalam promise.
Anda dapat mendaftarkan callback ini seperti:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
Satu-satunya batasan adalah callback "match" harus secara sinkron menampilkan nilai
yang benar, Anda tidak dapat melakukan tugas asinkron. Alasannya adalah karena
Router
harus merespons peristiwa pengambilan secara sinkron atau memungkinkan masuk
ke peristiwa pengambilan lainnya.
Biasanya callback "handler" akan menggunakan salah satu strategi yang disediakan oleh workbox-strategies seperti:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
Di halaman ini, kita akan berfokus pada workbox-routing
, tetapi Anda dapat
mempelajari lebih lanjut strategi ini terkait strategi kotak kerja.
Cara Mendaftarkan Rute Ekspresi Reguler
Praktik yang umum adalah menggunakan ekspresi reguler, bukan callback "match". Workbox membuatnya mudah untuk diimplementasikan seperti:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
Untuk permintaan dari asal yang sama, ekspresi reguler ini akan cocok selama URL permintaan cocok dengan ekspresi reguler.
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
Namun, untuk permintaan lintas origin, ekspresi reguler harus cocok dengan awal URL. Alasannya adalah bahwa
tidak mungkin dengan ekspresi reguler new RegExp('/styles/.*\\.css')
yang Anda inginkan untuk mencocokkan file CSS pihak ketiga.
- https://cdn.third-party-site.com/styles/main.css
- https://cdn.third-party-site.com/styles/nested/file.css
- https://cdn.third-party-site.com/nested/styles/directory.css
Jika menginginkan perilaku ini, Anda hanya perlu memastikan bahwa ekspresi reguler cocok dengan awal URL. Jika ingin mencocokkan permintaan untuk https://cdn.third-party-site.com
, kita dapat menggunakan ekspresi reguler new RegExp('https://cdn\\.third-party-site\\.com.*/styles/.*\\.css')
.
- https://cdn.third-party-site.com/styles/main.css
- https://cdn.third-party-site.com/styles/nested/file.css
- https://cdn.third-party-site.com/nested/styles/directory.css
Jika ingin mencocokkan pihak lokal dan pihak ketiga, Anda dapat menggunakan karakter pengganti di awal ekspresi reguler, tetapi hal ini harus dilakukan dengan hati-hati untuk memastikan hal ini tidak menyebabkan perilaku yang tidak terduga di aplikasi web Anda.
Cara Mendaftarkan Rute Navigasi
Jika situs Anda adalah aplikasi web satu halaman, Anda dapat menggunakan
NavigationRoute
untuk
menampilkan respons spesifik untuk semua
permintaan navigasi.
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler);
registerRoute(navigationRoute);
Setiap kali pengguna membuka situs Anda di browser, permintaan untuk halaman akan menjadi permintaan navigasi dan halaman yang di-cache /app-shell.html
akan ditayangkan.
(Catatan: Halaman harus di-cache melalui workbox-precaching
atau melalui
langkah penginstalan Anda sendiri.)
Secara default, tindakan ini akan merespons semua permintaan navigasi. Jika ingin
membatasinya agar merespons sebagian URL, Anda dapat menggunakan opsi allowlist
dan denylist
untuk membatasi halaman mana yang akan cocok dengan rute ini.
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [new RegExp('/blog/')],
denylist: [new RegExp('/blog/restricted/')],
});
registerRoute(navigationRoute);
Satu-satunya hal yang perlu diperhatikan adalah bahwa denylist
akan menang jika URL berada di
allowlist
dan denylist
.
Menetapkan Pengendali Default
Jika ingin menyediakan "pengendali" untuk permintaan yang tidak cocok dengan rute, Anda dapat menetapkan pengendali default.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
Menetapkan Pengendali Tangkap
Jika ada rute yang menampilkan error, Anda dapat merekam dan menurunkan versi secara halus dengan menetapkan pengendali catch.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
Menentukan Rute untuk Permintaan Non-GET
Semua rute secara default diasumsikan untuk permintaan GET
.
Jika ingin merutekan permintaan lain, seperti permintaan POST
, Anda perlu menentukan metode saat mendaftarkan rute, seperti ini:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
Pencatatan Log Router
Anda akan dapat menentukan alur permintaan menggunakan log dari workbox-routing
yang akan menandai URL mana yang sedang diproses melalui Workbox.
Jika memerlukan informasi lebih panjang, Anda dapat menetapkan level log ke debug
untuk
melihat log pada permintaan yang tidak ditangani oleh Router. Lihat
panduan proses debug kami untuk mengetahui info selengkapnya tentang
menetapkan level log.
Penggunaan Lanjutan
Jika ingin memiliki kontrol lebih besar atas kapan Router Workbox diberikan
permintaan, Anda dapat membuat instance
Router
Anda sendiri dan memanggil
metode handleRequest()
setiap kali Anda ingin menggunakan router untuk merespons permintaan.
import {Router} from 'workbox-routing';
const router = new Router();
self.addEventListener('fetch', event => {
const {request} = event;
const responsePromise = router.handleRequest({
event,
request,
});
if (responsePromise) {
// Router found a route to handle the request.
event.respondWith(responsePromise);
} else {
// No route was found to handle the request.
}
});
Saat menggunakan Router
secara langsung, Anda juga harus menggunakan class Route
,
atau salah satu class yang diperluas untuk mendaftarkan rute.
import {Route, RegExpRoute, NavigationRoute, Router} from 'workbox-routing';
const router = new Router();
router.registerRoute(new Route(matchCb, handlerCb));
router.registerRoute(new RegExpRoute(new RegExp(...), handlerCb));
router.registerRoute(new NavigationRoute(handlerCb));
Jenis
NavigationRoute
NavigationRoute memudahkan pembuatan
workbox-routing.Route
yang cocok untuk browser
[permintaan navigasi]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests
.
Permintaan ini hanya akan cocok dengan Permintaan masuk yang
https://fetch.spec.whatwg.org/#concept-request-mode|mode
ditetapkan ke navigate
.
Secara opsional, Anda hanya dapat menerapkan rute ini ke subkumpulan permintaan navigasi
dengan menggunakan salah satu atau kedua parameter denylist
dan allowlist
.
Properti
-
void
Jika
denylist
danallowlist
diberikan,denylist
akan diprioritaskan dan permintaan tidak akan cocok dengan rute ini.Ekspresi reguler dalam
allowlist
dandenylist
dicocokkan dengan bagian gabungan [pathname
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname
dan [search
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search
dari URL yang diminta.Catatan: RegExp ini dapat dievaluasi terhadap setiap URL tujuan selama navigasi. Hindari penggunaan Ekspresi Reguler yang kompleks, atau pengguna mungkin akan mengalami keterlambatan saat membuka situs Anda.
Fungsi
constructor
terlihat seperti:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
Fungsi callback yang menampilkan Promise yang menghasilkan Respons.
-
NavigationRouteMatchOptions opsional
-
-
RouteHandlerObject opsional
-
HTTPMethod
-
void
Fungsi
setCatchHandler
terlihat seperti:(handler: RouteHandler) => {...}
-
Fungsi callback yang menampilkan Promise yang di-resolve ke Respons
-
NavigationRouteMatchOptions
Properti
-
RegExp[] opsional
-
RegExp[] opsional
RegExpRoute
RegExpRoute memudahkan pembuatan ekspresi reguler berbasis
workbox-routing.Route
.
Untuk permintaan origin yang sama, RegExp hanya perlu mencocokkan sebagian URL. Untuk permintaan terhadap server pihak ketiga, Anda harus menentukan RegExp yang cocok dengan awal URL.
Properti
-
konstruktor
void
Jika ekspresi reguler berisi [capture groups]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
, nilai yang diambil akan diteruskan ke argumenworkbox-routing~handlerCallback
params
.Fungsi
constructor
terlihat seperti:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
Ekspresi reguler yang akan dicocokkan dengan URL.
-
handler
Fungsi callback yang menampilkan Promise yang menghasilkan Respons.
-
method
HTTPMethod opsional
-
akan menampilkan
-
-
catchHandler
RouteHandlerObject opsional
-
handler
-
cocok
-
method
HTTPMethod
-
setCatchHandler
void
Fungsi
setCatchHandler
terlihat seperti:(handler: RouteHandler) => {...}
-
handler
Fungsi callback yang menampilkan Promise yang di-resolve ke Respons
-
Route
Route
terdiri dari sepasang fungsi callback, "match" dan "pengendali".
Callback "match" menentukan apakah rute harus digunakan untuk "menangani"
permintaan dengan menampilkan nilai yang tidak salah jika memungkinkan. Callback "pengendali"
dipanggil saat ada kecocokan dan harus menampilkan Promise yang di-resolve
ke Response
.
Properti
-
konstruktor
void
Konstruktor untuk class Route.
Fungsi
constructor
terlihat seperti:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
cocok
Fungsi callback yang menentukan apakah rute cocok dengan peristiwa
fetch
tertentu dengan menampilkan nilai non-falsy. -
handler
Fungsi callback yang menampilkan Promise yang di-resolve ke sebuah Respons.
-
method
HTTPMethod opsional
-
akan menampilkan
-
-
catchHandler
RouteHandlerObject opsional
-
handler
-
cocok
-
method
HTTPMethod
-
setCatchHandler
void
Fungsi
setCatchHandler
terlihat seperti:(handler: RouteHandler) => {...}
-
handler
Fungsi callback yang menampilkan Promise yang di-resolve ke Respons
-
Router
Router dapat digunakan untuk memproses FetchEvent
menggunakan satu atau beberapa
workbox-routing.Route
, yang merespons dengan Response
jika
ada rute yang cocok.
Jika tidak ada rute yang cocok dengan permintaan yang diberikan, Router akan menggunakan pengendali "default" jika ada yang ditentukan.
Jika Rute yang cocok menampilkan error, Router akan menggunakan pengendali "catch" jika salah satunya ditentukan untuk menangani masalah dengan baik dan merespons dengan Permintaan.
Jika sebuah permintaan cocok dengan beberapa rute, rute yang terdaftar paling awal akan digunakan untuk merespons permintaan tersebut.
Properti
-
konstruktor
void
Menginisialisasi Router baru.
Fungsi
constructor
terlihat seperti:() => {...}
-
akan menampilkan
-
-
routes
Map<HTTPMethodRoute[]>
-
addCacheListener
void
Menambahkan pemroses peristiwa pesan agar URL dapat di-cache dari jendela. Hal ini berguna untuk meng-cache resource yang dimuat di halaman sebelum pekerja layanan mulai mengontrolnya.
Format data pesan yang dikirim dari jendela harus seperti berikut. Dalam hal ini, array
urlsToCache
dapat terdiri dari string URL atau array string URL + objekrequestInit
(sama seperti yang akan Anda teruskan kefetch()
).{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
Fungsi
addCacheListener
terlihat seperti:() => {...}
-
addFetchListener
void
Menambahkan pemroses peristiwa pengambilan untuk merespons peristiwa saat rute cocok dengan permintaan peristiwa.
Fungsi
addFetchListener
terlihat seperti:() => {...}
-
findMatchingRoute
void
Memeriksa permintaan dan URL (dan secara opsional peristiwa) terhadap daftar rute yang terdaftar. Jika ada kecocokan, menampilkan rute yang sesuai beserta parameter apa pun yang dihasilkan oleh kecocokan.
Fungsi
findMatchingRoute
terlihat seperti:(options: RouteMatchCallbackOptions) => {...}
-
akan menampilkan
objek
Objek dengan properti
route
danparams
. Kolom ini akan diisi jika rute yang cocok ditemukan atauundefined
jika tidak.
-
-
handleRequest
void
Terapkan aturan perutean ke objek FetchEvent untuk mendapatkan Respons dari pengendali Rute yang sesuai.
Fungsi
handleRequest
terlihat seperti:(options: object) => {...}
-
opsi
objek
-
event
ExtendableEvent
Peristiwa yang memicu permintaan.
-
minta
Permintaan
Permintaan yang akan ditangani.
-
-
akan menampilkan
Promise<Response>
Promise ditampilkan jika rute yang terdaftar dapat menangani permintaan. Jika tidak ada rute yang cocok dan tidak ada
defaultHandler
,undefined
akan ditampilkan.
-
-
registerRoute
void
Mendaftarkan rute dengan router.
Fungsi
registerRoute
terlihat seperti:(route: Route) => {...}
-
rute
Rute untuk mendaftar.
-
-
setCatchHandler
void
Jika sebuah Rute menampilkan error saat menangani permintaan,
handler
ini akan dipanggil dan diberi kesempatan untuk memberikan respons.Fungsi
setCatchHandler
terlihat seperti:(handler: RouteHandler) => {...}
-
handler
Fungsi callback yang menampilkan Promise yang menghasilkan Respons.
-
-
setDefaultHandler
void
Tentukan
handler
default yang dipanggil saat tidak ada rute yang secara eksplisit cocok dengan permintaan masuk.Setiap metode HTTP ('GET', 'POST', dll.) mendapatkan pengendali defaultnya sendiri.
Tanpa pengendali default, permintaan yang tidak cocok akan bertentangan dengan jaringan seolah-olah tidak ada pekerja layanan.
Fungsi
setDefaultHandler
terlihat seperti:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
handler
Fungsi callback yang menampilkan Promise yang menghasilkan Respons.
-
method
HTTPMethod opsional
-
-
unregisterRoute
void
Membatalkan pendaftaran rute dengan router.
Fungsi
unregisterRoute
terlihat seperti:(route: Route) => {...}
-
rute
Rute untuk membatalkan pendaftaran.
-
Metode
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
Daftarkan RegExp, string, atau fungsi dengan mudah menggunakan strategi cache ke instance Router singleton.
Metode ini akan membuat Rute untuk Anda jika diperlukan dan
memanggil workbox-routing.Router#registerRoute
.
Parameter
-
rekam video
string | RegExp | RouteMatchCallback | Route
Jika parameter pengambilan adalah
Route
, semua argumen lainnya akan diabaikan. -
handler
RouteHandler opsional
-
method
HTTPMethod opsional
Hasil
-
Route
yang dihasilkan.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
Jika sebuah Rute menampilkan error saat menangani permintaan, handler
ini akan dipanggil dan diberi kesempatan untuk memberikan respons.
Parameter
-
handler
Fungsi callback yang menampilkan Promise yang menghasilkan Respons.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
Tentukan handler
default yang dipanggil saat tidak ada rute yang secara eksplisit cocok dengan permintaan masuk.
Tanpa pengendali default, permintaan yang tidak cocok akan bertentangan dengan jaringan seolah-olah tidak ada pekerja layanan.
Parameter
-
handler
Fungsi callback yang menampilkan Promise yang menghasilkan Respons.