קובץ שירות (service worker) יכול ליירט בקשות רשת עבור דף. הוא עשוי להגיב לדפדפן עם תוכן שנשמר במטמון, תוכן מהרשת או תוכן שנוצר ב-Service Worker.
workbox-routing
הוא מודול שמאפשר לנתב בקלות את הבקשות האלה לפונקציות שונות שמספקות תשובות.
כיצד מתבצע הניתוב
כשבקשת רשת גורמת לאירוע אחזור של Service Worker, workbox-routing
ינסה להגיב לבקשה באמצעות הנתיבים ורכיבי ה-handler שסופקו.
הנקודות העיקריות שיש לציין למעלה הם:
יש חשיבות לשיטה לשליחת הבקשה. כברירת מחדל, נתיבים רשומים עבור בקשות
GET
. כדי ליירט בקשות מסוגים אחרים, צריך לציין את השיטה.הסדר של רישום הנתיב חשוב. אם רשומים כמה נתיבים שיכולים לטפל בבקשה, הנתיב שרשום ראשון ישמש במענה לבקשה.
יש כמה דרכים לרשום מסלול: אפשר להשתמש בקריאות חוזרות, בביטויים רגולריים או במופעים של נתיב.
התאמה וטיפול במסלולים
ל-"route" בתיבת העבודה יש לא יותר משתי פונקציות: פונקציה "matching" (התאמה) שקובעת אם המסלול צריך להתאים לבקשה, ופונקציית "handling" (טיפול), שאמורה לטפל בבקשה ולהגיב בתגובה.
ב-Workbox יש כמה כלי עזר שיאפשרו לכם לבצע את ההתאמה והטיפול, אבל אם אי פעם תרצו התנהגות אחרת, האפשרות הטובה ביותר היא לכתוב התאמה מותאמת אישית ופונקציה של handler.
פונקציית התאמה של קריאה חוזרת מועברת באמצעות ExtendableEvent
, Request
ואובייקט URL
שאפשר להתאים על ידי החזרת ערך מהימן. לדוגמה פשוטה, אפשר לבצע התאמה מול כתובת URL ספציפית, כך:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
כדי לקבל מידע על רוב התרחישים לדוגמה, אפשר לבדוק או לבדוק את url
או את request
.
פונקציית קריאה חוזרת של handler תקבל את אותם אובייקט ExtendableEvent
, Request
ו-URL
אובייקט, יחד עם הערך params
, שהוא הערך שהפונקציה 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,
});
};
ה-handler שלך חייב להחזיר הבטחה שמובילה ל-Response
. בדוגמה הזו נשתמש ב-async
וב-await
.
מתחת למכסה הקדמי, הערך המוחזר של Response
יהיה מוקף בהבטחה.
אפשר לרשום את הקריאות החוזרות (callback) כך:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
המגבלה היחידה היא שהקריאה החוזרת 'התאמה' חייבת להחזיר ערך מהימן שאי אפשר לבצע עבודה אסינכרונית. הסיבה לכך היא שה-Router
חייב להגיב באופן סינכרוני לאירוע האחזור או לאפשר מעבר לאירועי אחזור אחרים.
בדרך כלל, הקריאה החוזרת (callback) של "handler" תשתמש באחת מהאסטרטגיות שמספק אסטרטגיות ארגז העבודה, כגון:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
בדף הזה נתמקד ב-workbox-routing
אבל תוכלו לקרוא מידע נוסף על האסטרטגיות האלה לגבי אסטרטגיות של ארגזי עבודה.
איך רושמים נתיב ביטויים רגולריים
שיטה נפוצה היא להשתמש בביטוי רגולרי במקום בקריאה חוזרת (callback) של "התאמה". עם Workbox קל ליישם את זה כך:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
לבקשות מאותו מקור, הביטוי הרגולרי הזה יתאים כל עוד כתובת ה-URL של הבקשה תואמת לביטוי הרגולרי.
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
עם זאת, בבקשות ממקורות שונים, ביטויים רגולריים חייבים להתאים לתחילת כתובת ה-URL. הסיבה לכך היא שלא סביר שבאמצעות ביטוי רגולרי new RegExp('/styles/.*\\.css')
התכוונת להתאים לקובצי 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
אם רצתם את ההתנהגות הזו, צריך רק לוודא שהביטוי הרגולרי תואם לתחילת כתובת ה-URL. כדי להתאים את הבקשות של https://cdn.third-party-site.com
, אפשר להשתמש בביטוי הרגולרי 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
אם רוצים להתאים גם צד שלישי וגם צד שלישי, אפשר להשתמש בתו כללי לחיפוש בתחילת הביטוי הרגולרי, אבל צריך לעשות זאת בזהירות כדי להבטיח שההתנהגות לא תגרום להתנהגות לא צפויה באפליקציית האינטרנט.
איך לרשום מסלול ניווט
במקרה שהאתר הוא אפליקציה בדף יחיד, אפשר להשתמש ב-NavigationRoute
כדי להחזיר תגובה ספציפית לכל בקשות הניווט.
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);
בכל פעם שמשתמש ייכנס לאתר בדפדפן, הבקשה לדף תהיה בקשת ניווט, והיא תוצג בדף /app-shell.html
שנשמר במטמון.
(הערה: הדף אמור להיות שמור במטמון דרך workbox-precaching
או דרך שלב ההתקנה שלכם).
כברירת מחדל, התגובה הזו תגיב לכל בקשות הניווט. אם רוצים להגביל אותה ולתגובה לקבוצת משנה של כתובות URL, אפשר להשתמש באפשרויות allowlist
ו-denylist
כדי להגביל את הדפים שיתאימו למסלול הזה.
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);
הדבר היחיד שצריך לדעת הוא שהשדה denylist
ינצח אם כתובת URL כלשהי נמצאת גם ב-allowlist
וגם ב-denylist
.
הגדרה של מטפל ברירת מחדל
אם רוצים לספק 'handler' לבקשות שלא תואמות למסלול, אפשר להגדיר handler ברירת מחדל.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
הגדרה של אפליקציית תופסת
אם מופיעה שגיאה באחד מהמסלולים, אפשר לתעד ולפגוע בצורה חיננית על ידי הגדרת handler של תפיסה.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
הגדרת נתיב לבקשות שאינן GET
כברירת מחדל, ההנחה היא שכל המסלולים שייכים לבקשות של GET
.
אם אתם רוצים לנתב בקשות אחרות, כמו בקשת POST
, עליכם להגדיר את ה-method בזמן רישום המסלול, כך:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
רישום נתב
צריכה להיות לכם אפשרות לקבוע את רצף הבקשה באמצעות היומנים מ-workbox-routing
, שידגישו אילו כתובות URL מעובדות באמצעות Workbox.
אם אתם צריכים מידע מפורט יותר, אפשר להגדיר את רמת היומן ל-debug
על מנת לראות יומנים של בקשות שלא מטופלות על ידי הנתב. מידע נוסף על הגדרת רמת היומן זמין במדריך לניפוי באגים.
שימוש מתקדם
אם אתם רוצים שתהיה לכם יותר שליטה על המועד שבו מתקבלות בקשות של נתב Workbox, תוכלו ליצור מכונה משלכם ב-Router
ולהפעיל את השיטה handleRequest()
בכל פעם שתרצו להשתמש בנתב כדי להגיב לבקשה.
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.
}
});
כשמשתמשים ב-Router
ישירות, צריך להשתמש גם במחלקה Route
או בכל אחת מהמחלקות המורחבות כדי לרשום מסלולים.
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));
סוגים
NavigationRoute
בעזרת NavigationRoute תוכלו ליצור בקלות workbox-routing.Route
שתואם לדפדפן [בקשות ניווט]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests
.
היא תתאים רק לבקשות נכנסות שבהן השדה https://fetch.spec.whatwg.org/#concept-request-mode|mode
מוגדר ל-navigate
.
אפשר להחיל את המסלול הזה רק על קבוצת משנה של בקשות ניווט, באמצעות אחד מהפרמטרים denylist
ו-allowlist
או שניהם.
תכונות
-
void
אם גם
denylist
וגםallowlist
תספקו עדיפות, השדהdenylist
יקבל עדיפות והבקשה לא תתאים למסלול הזה.הביטויים הרגולריים ב-
allowlist
וב-denylist
מותאמים לחלקים המשורשרים [pathname
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname
ו-[search
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search
של כתובת ה-URL המבוקשת.הערה: במהלך הניווט, ייתכן שערכי ה-RegExp האלה ייבדקו ביחס לכל כתובת יעד. כדאי להימנע משימוש בביטויי רגולריים מורכבים, אחרת המשתמשים עשויים לראות עיכובים במהלך הניווט באתר.
הפונקציה
constructor
נראית כך:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה, והתוצאה היא תשובה.
-
NavigationRouteMatchOptions אופציונלי
-
-
RouteHandlerObject אופציונלי
-
HTTPMethod
-
void
הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה לתגובה
-
NavigationRouteMatchOptions
תכונות
-
RegExp[] אופציונלי
-
RegExp[] אופציונלי
RegExpRoute
בעזרת RegExpRoute, קל ליצור ביטוי רגולרי שמבוסס על workbox-routing.Route
.
בבקשות מאותו מקור, RegExp צריך להתאים רק לחלק מכתובת ה-URL. בבקשות שנשלחות נגד שרתים של צד שלישי, צריך להגדיר ביטוי רגולרי (regex) שתואם לתחילת כתובת ה-URL.
תכונות
-
Constructor
void
אם הביטוי הרגולרי מכיל [capture groups]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
, הערכים שתועדו יועברו לארגומנטworkbox-routing~handlerCallback
params
.הפונקציה
constructor
נראית כך:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
הביטוי הרגולרי שיש להתאים מול כתובות האתרים.
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה, והתוצאה היא תשובה.
-
method
HTTPMethod אופציונלי
-
החזרות
-
-
catchHandler
RouteHandlerObject אופציונלי
-
handler
-
התאמה
-
method
HTTPMethod
-
setCatchHandler
void
הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה לתגובה
-
Route
Route
מורכב מזוג פונקציות של קריאה חוזרת (callback), "match" ו-"handler".
הקריאה החוזרת (callback) בשדה 'התאמה' קובעת אם יש להשתמש במסלול על מנת "לטפל" בבקשה, על ידי החזרת ערך שאינו מזויף, אם אפשר. הקריאה החוזרת (callback) של ה-handler מופעלת כשיש התאמה, והיא צריכה להחזיר Promise שמסתיימת ב-Response
.
תכונות
-
Constructor
void
בנאי של מחלקה מסוג 'מסלול'.
הפונקציה
constructor
נראית כך:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
התאמה
פונקציית קריאה חוזרת שקובעת אם המסלול תואם לאירוע
fetch
נתון על ידי החזרת ערך שאינו זיוף. -
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה לתשובה.
-
method
HTTPMethod אופציונלי
-
החזרות
-
-
catchHandler
RouteHandlerObject אופציונלי
-
handler
-
התאמה
-
method
HTTPMethod
-
setCatchHandler
void
הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה לתגובה
-
Router
אפשר להשתמש בנתב כדי לעבד FetchEvent
באמצעות workbox-routing.Route
אחד או יותר, ולהגיב באמצעות Response
אם קיים מסלול תואם.
אם אין מסלול שתואם לבקשה נתונה, הנתב ישתמש ב-handler שמוגדר כברירת מחדל, אם יש כזה.
אם מופיעה שגיאה במסלול התואם, הנתב ישתמש ב-handler של "catch" אם הוא מוגדר לטפל בבעיות בצורה חלקה ולהגיב עם בקשה.
אם בקשה תואמת למספר מסלולים, ייעשה שימוש במסלול הרשום המוקדם ביותר לצורך מענה לבקשה.
תכונות
-
Constructor
void
הפעלה של נתב חדש.
הפונקציה
constructor
נראית כך:() => {...}
-
החזרות
-
-
נתיבים
Map<HTTPMethodRoute[]>
-
addCacheListener
void
מוסיף האזנה לאירוע הודעה לכתובות URL שנשמרו במטמון מהחלון. אפשרות זו שימושית לשמירה במטמון של משאבים שנטענו בדף לפני ש-Service Worker התחיל לשלוט בו.
הפורמט של נתוני ההודעה שנשלחים מהחלון אמור להיות: כאשר המערך
urlsToCache
יכול להכיל מחרוזות של כתובות URL או מערך של מחרוזת כתובת URL + אובייקטrequestInit
(אותו הערך שמעבירים אלfetch()
).{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
הפונקציה
addCacheListener
נראית כך:() => {...}
-
addFetchListener
void
הוספת מעבד אירוע אחזור כדי להגיב לאירועים כאשר מסלול תואם לבקשת האירוע.
הפונקציה
addFetchListener
נראית כך:() => {...}
-
findMatchingRoute
void
הפונקציה בודקת בקשה וכתובת URL (ואופציונלית גם אירוע) מול רשימת המסלולים הרשומים, ואם יש התאמה, מחזירה את המסלול התואם יחד עם כל הפרמטרים שנוצרו על ידי ההתאמה.
הפונקציה
findMatchingRoute
נראית כך:(options: RouteMatchCallbackOptions) => {...}
-
אפשרויות
-
החזרות
אובייקט
אובייקט עם המאפיינים
route
ו-params
. הם מאוכלסים אם נמצא מסלול תואם אוundefined
אחרת.
-
-
handleRequest
void
מחילים את כללי הניתוב על אובייקט FetchEvent כדי לקבל תשובה מה-handler של הנתיב המתאים.
הפונקציה
handleRequest
נראית כך:(options: object) => {...}
-
אפשרויות
אובייקט
-
אירוע
ExtendableEvent
האירוע שהקפיץ את הבקשה.
-
בקשה
בקשה
הבקשה לטיפול.
-
-
החזרות
הבטחה<Response>
מתקבלת הבטחה אם מסלול רשום יכול לטפל בבקשה. במקרה שלא נמצא מסלול תואם ואין
defaultHandler
, מוחזרundefined
.
-
-
registerRoute
void
רישום מסלול בנתב.
הפונקציה
registerRoute
נראית כך:(route: Route) => {...}
-
נתיב
המסלול להרשמה.
-
-
setCatchHandler
void
אם מסלול גורם לשגיאה במהלך טיפול בבקשה, תתבצע קריאה ל-
handler
הזה ותינתן לו הזדמנות להגיב.הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה, והתוצאה היא תשובה.
-
-
setDefaultHandler
void
מגדירים ברירת מחדל של
handler
שיופעל אם אין מסלולים התואמים באופן מפורש לבקשה הנכנסת.כל שיטת HTTP ('GET', 'POST' וכו') מקבלת handler משלה שמוגדר כברירת מחדל.
בלי handler שמוגדר כברירת מחדל, בקשות שלא הותאמו יופעלו ברשת, כאילו לא קיים קובץ שירות (service worker).
הפונקציה
setDefaultHandler
נראית כך:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה, והתוצאה היא תשובה.
-
method
HTTPMethod אופציונלי
-
-
unregisterRoute
void
מבטל רישום של מסלול עם הנתב.
הפונקציה
unregisterRoute
נראית כך:(route: Route) => {...}
-
נתיב
הנתיב לביטול הרישום.
-
שיטות
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
רישום בקלות של ביטוי רגולרי, מחרוזת או פונקציה באסטרטגיית שמירה במטמון במכונה של נתב בודד.
במקרה הצורך, השיטה הזו תיצור מסלול בשבילכם ותתקשר למספר workbox-routing.Router#registerRoute
.
פרמטרים
-
צילום
string | RegExp | RouteMatchCallback | נתיב
אם פרמטר הלכידה הוא
Route
, המערכת תתעלם מכל שאר הארגומנטים. -
handler
RouteHandler אופציונלי
-
method
HTTPMethod אופציונלי
החזרות
-
הערך
Route
שנוצר.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
אם מסלול גורם לשגיאה במהלך טיפול בבקשה, תתבצע קריאה ל-handler
הזה ותינתן לו הזדמנות להגיב.
פרמטרים
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה, והתוצאה היא תשובה.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
מגדירים ברירת מחדל של handler
שיופעל אם אין מסלולים התואמים באופן מפורש לבקשה הנכנסת.
בלי handler שמוגדר כברירת מחדל, בקשות שלא הותאמו יופעלו ברשת, כאילו לא קיים קובץ שירות (service worker).
פרמטרים
-
handler
פונקציית קריאה חוזרת (callback) שמחזירה הבטחה, והתוצאה היא תשובה.