קובץ שירות (service worker) יכול ליירט בקשות רשת לדפים. הוא עשוי להגיב ל: דפדפן עם תוכן שנשמר במטמון, תוכן מהרשת או תוכן שנוצר בקובץ השירות (service worker).
workbox-routing
הוא מודול שמאפשר "לנתב" בקלות הבקשות האלה
פונקציות שונות שמספקות תשובות.
איך מתבצע הניתוב
כשבקשת רשת גורמת לאירוע אחזור של Service Worker, workbox-routing
ינסה להגיב לבקשה באמצעות המסלולים ורכיבי ה-handler שסופקו.
הנקודות העיקריות שכדאי לשים לב אליהן הן:
חשוב לזכור את השיטה של הבקשה. כברירת מחדל, המסלולים רשומים עבור
GET
בקשות. אם ברצונך ליירט סוגים אחרים של בקשות, צריך כדי לציין את ה-method.חשוב לסדר את הרישום של המסלול. אם יש כמה מסלולים רשום שיכול לטפל בבקשה, המסלול שנרשם ראשון ישמש לתגובה לבקשה.
יש כמה דרכים לרשום מסלול: אפשר להשתמש בקריאות חוזרות, ביטויים או מופעים של 'נתיב'.
התאמה וטיפול במסלולים
"נתיב" בתיבת העבודה היא לא יותר משתי פונקציות: פונקציה כדי לקבוע אם המסלול צריך להתאים לבקשה ול'טיפול' פונקציה, שאמורה לטפל בבקשה ולהגיב בתגובה.
תיבת העבודה כוללת מספר עוזרים לבצע את ההתאמה והטיפול אבל אם אי פעם תרצו למצוא התנהגות אחרת, ההתאמה האישית והפונקציה של ה-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
יהיה מוקף בהבטחה.
אפשר לרשום את הקריאות החוזרות האלה, למשל:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
המגבלה היחידה היא שה"התאמה" הקריאה החוזרת (callback) חייבת לסנכרן באופן סינכרוני
ערך זה, לא ניתן לבצע עבודה אסינכרונית. הסיבה לכך היא
הערך של Router
חייב להגיב באופן סינכרוני לאירוע האחזור או לאפשר שגיאה
לאירועי אחזור אחרים.
בדרך כלל ה-handler (המטפל) ייעשה שימוש באחת מהאסטרטגיות שצוינו ב-callback לפי אסטרטגיות תיבת עבודה כמו:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
בדף הזה נתמקד בנושא workbox-routing
אבל אפשר
מידע נוסף על האסטרטגיות האלה בנושא אסטרטגיות של תיבות עבודה
איך לרשום נתיב של ביטוי רגולרי
שיטה נפוצה היא להשתמש בביטוי רגולרי במקום ב'התאמה' קריאה חוזרת. בעזרת 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' לבקשות שלא תואמות למסלול, אתם יכול להגדיר handler ברירת מחדל.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
הגדרת מטפל תפיסה
במקרה שהמסלולים שלך מקפיצים שגיאה, אפשר לצלם ו לפגוע באלגנטיות על ידי הגדרת handler של קליטה.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
הגדרת נתיב לבקשות שאינן מסוג GET
ההנחה היא שכל המסלולים הם עבור בקשות GET
כברירת מחדל.
כדי לנתב בקשות אחרות, כמו בקשה של POST
, צריך
כדי להגדיר את השיטה בזמן רישום המסלול, למשל:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
רישום ביומן של נתב
אפשר לזהות את זרימת הבקשה בעזרת היומנים של
workbox-routing
, שידגיש אילו כתובות URL נמצאות בתהליך עיבוד
דרך תיבת העבודה.
אם דרוש לך מידע מפורט נוסף, אפשר להגדיר את רמת היומן ל-debug
כך:
לצפות ביומנים של בקשות שלא טופלו על ידי הנתב. כדאי לעיין
במדריך לניפוי באגים תוכלו למצוא מידע נוסף על
בהגדרה של רמת היומן.
שימוש מתקדם
אם אתם רוצים שתהיה לכם יותר שליטה על המועד שבו ניתן הנתב של תיבת העבודה
תוכל ליצור בקשות משלך,
מופע וקריאה של Router
השעה handleRequest()
method בכל פעם שרוצים להשתמש בנתב כדי להגיב לבקשה.
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
ניווט במסלול מאפשר ליצור בקלות
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
, או שניהם.
מאפיינים
-
ריק
אם תספקו גם את
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
חלקים של כתובת האתר המבוקשת.הערה: המערכת עשויה להעריך את ביטויים רגולריים אלה ביחס לכל כתובת יעד במהלך ניווט. עדיף להימנע משימוש complex RegExps, אחרת, המשתמשים עשויים לראות עיכובים בזמן הניווט באתר.
הפונקציה
constructor
נראית כך:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
התקשרות חזרה מחזירה 'Promise' (הבטחה) שמובילה לתגובה.
-
NavigationRouteMatchOptions אופציונלי
-
-
RouteHandlerObject אופציונלי
-
HTTPMethod
-
ריק
הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
התקשרות חזרה פונקציה שמחזירה תגובה ל-Promise
-
NavigationRouteMatchOptions
מאפיינים
-
RegExp[] אופציונלי
-
RegExp[] אופציונלי
RegExpRoute
באמצעות RegExpRoute קל ליצור ביטוי רגולרי שמבוסס על
workbox-routing.Route
בבקשות ממקור זהה, הפרמטר RegExp צריך להתאים רק לחלק מכתובת ה-URL. עבור בהתחלה של כתובת ה-URL.
מאפיינים
-
constructor
ריק
אם הביטוי הרגולרי מכיל [לכידת קבוצות]
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
הביטוי הרגולרי שצריך להתאים מול כתובות URL.
-
handler
התקשרות חזרה מחזירה 'Promise' (הבטחה) שמובילה לתגובה.
-
method
שיטת HTTP אופציונלית
-
החזרות
-
-
catchHandler
RouteHandlerObject אופציונלי
-
handler
-
התאמה
-
method
HTTPMethod
-
setCatchHandler
ריק
הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
handler
התקשרות חזרה פונקציה שמחזירה תגובה ל-Promise
-
Route
Route
מורכב מזוג פונקציות קריאה חוזרת – "match" ו-'handler'.
"התאמה" קריאה חוזרת (callback) קובעת אם צריך להשתמש במסלול כדי "לטפל" A
באמצעות החזרת ערך שאינו קביל, אם הוא יכול. ה-"handler" התקשרות חזרה
נקרא כאשר יש התאמה והוא צריך להחזיר הבטחה שפותרת
Response
.
מאפיינים
-
constructor
ריק
בונה המחלקה במסלול.
הפונקציה
constructor
נראית כך:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
התאמה
פונקציית קריאה חוזרת שקובעת אם המסלול תואם האירוע
fetch
שמוחזר לערך שאינו דמה. -
handler
התקשרות חזרה פונקציה שמחזירה תגובה ל-Promise.
-
method
שיטת HTTP אופציונלית
-
החזרות
-
-
catchHandler
RouteHandlerObject אופציונלי
-
handler
-
התאמה
-
method
HTTPMethod
-
setCatchHandler
ריק
הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
handler
התקשרות חזרה פונקציה שמחזירה תגובה ל-Promise
-
Router
אפשר להשתמש בנתב כדי לעבד FetchEvent
באמצעות נתב אחד או יותר
workbox-routing.Route
, תגובה עם Response
אם
קיים מסלול תואם.
אם אין מסלול שמתאים לבקשה מסוימת, הנתב ישתמש בברירת המחדל handler, אם מוגדר כזה.
אם המסלול התואם יקפיץ שגיאה, הנתב ישתמש ב"תפיסה" (catch) את המטפל אם מוגדר לטפל בבעיות בצורה חלקה ולתת מענה בקשה.
אם הבקשה תואמת לכמה מסלולים, המסלול המוקדם ביותר שרשום במערכת ישמשו לתגובה לבקשה.
מאפיינים
-
constructor
ריק
הפעלת נתב חדש.
הפונקציה
constructor
נראית כך:() => {...}
-
החזרות
-
-
נתיבים
Map<HTTPMethodRoute[]>
-
addCacheListener
ריק
הוספה של האזנה לאירועי הודעה לכתובות URL לשמירה במטמון מהחלון. התכונה הזו שימושית לשמירה במטמון של משאבים שנטענו בדף לפני התאריך שבו Service Worker התחיל לשלוט בו.
הפורמט של נתוני ההודעה שנשלחים מהחלון אמור להיות בפורמט הבא. כאשר המערך
urlsToCache
יכול להכיל מחרוזות של כתובות URL או מערך של מחרוזת URL + אובייקטrequestInit
(כמו שמעבירים אלfetch()
).{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
הפונקציה
addCacheListener
נראית כך:() => {...}
-
addFetchListener
ריק
הוספה של האזנה לאירועי אחזור כדי להגיב לאירועים כשמסלול תואם לבקשת האירוע.
הפונקציה
addFetchListener
נראית כך:() => {...}
-
findMatchingRoute
ריק
הפונקציה בודקת בקשה וכתובת URL (ואופציונלית גם אירוע) מול הרשימה של למסלולים רשומים, ואם יש התאמה, הפונקציה מחזירה של הפרמטר הזה, יחד עם הפרמטרים שנוצרו על ידי ההתאמה.
הפונקציה
findMatchingRoute
נראית כך:(options: RouteMatchCallbackOptions) => {...}
-
אפשרויות
-
החזרות
אובייקט
אובייקט עם המאפיינים
route
ו-params
. הם מאוכלסים אם נמצא מסלול תואם אוundefined
אחרת.
-
-
handleRequest
ריק
יש להחיל את כללי הניתוב על אובייקט FetchEvent כדי לקבל תשובה ה-handler של הנתיב המתאים.
הפונקציה
handleRequest
נראית כך:(options: object) => {...}
-
אפשרויות
אובייקט
-
אירוע
ExtendableEvent
האירוע שהפעיל בקשה.
-
בקשה
בקשה
הבקשה לטיפול.
-
-
החזרות
Promise<Response>
הבטחה מוחזרת אם המסלול הרשום יכול לטפל בבקשה. אם לא נמצאה התאמה המסלול ואין
defaultHandler
, מוחזרundefined
.
-
-
registerRoute
ריק
רושם מסלול בנתב.
הפונקציה
registerRoute
נראית כך:(route: Route) => {...}
-
נתיב
המסלול לרישום.
-
-
setCatchHandler
ריק
אם מופיעה שגיאה במסלול במהלך הטיפול בבקשה, הערך של
handler
תתבצע שיחה ותינתן לו הזדמנות לספק תשובה.הפונקציה
setCatchHandler
נראית כך:(handler: RouteHandler) => {...}
-
handler
התקשרות חזרה פונקציה שמחזירה את Promise שמובילה לתשובה.
-
-
setDefaultHandler
ריק
הגדרת
handler
כברירת מחדל, שתיקרא כאשר אין מסלולים באופן מפורש תואמים לבקשה הנכנסת.כל method של HTTP ('GET', 'POST' וכו') מקבלת handler משלה שמוגדר כברירת מחדל.
ללא handler שמוגדר כברירת מחדל, בקשות שלא מולאו יעברו אל כאילו אין קובץ שירות (service worker).
הפונקציה
setDefaultHandler
נראית כך:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
handler
התקשרות חזרה פונקציה שמחזירה את Promise שמובילה לתשובה.
-
method
שיטת HTTP אופציונלית
-
-
unregisterRoute
ריק
מבטל את הרישום של מסלול באמצעות הנתב.
הפונקציה
unregisterRoute
נראית כך:(route: Route) => {...}
-
נתיב
הנתיב לביטול הרישום.
-
שיטות
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
רישום בקלות של RegExp, מחרוזת או פונקציה באמצעות שמירה במטמון למכונה של רוטר סינגלטון.
השיטה הזו תיצור עבורך נתיב במקרה הצורך,
קוראים לפונקציה workbox-routing.Router#registerRoute
.
פרמטרים
-
צילום
string | RegExp | RouteMatchCallback | מסלול
אם פרמטר הצילום הוא
Route
, המערכת תתעלם מכל שאר הארגומנטים. -
handler
RouteHandler אופציונלי
-
method
שיטת HTTP אופציונלית
החזרות
-
הקובץ
Route
שנוצר.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
אם מופיעה שגיאה במסלול במהלך הטיפול בבקשה, הערך של handler
תתבצע שיחה ותינתן לו הזדמנות לספק תשובה.
פרמטרים
-
handler
התקשרות חזרה מחזירה 'Promise' (הבטחה) שמובילה לתגובה.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
הגדרת handler
כברירת מחדל, שתיקרא כאשר אין מסלולים באופן מפורש
תואמים לבקשה הנכנסת.
ללא handler שמוגדר כברירת מחדל, בקשות שלא מולאו יעברו אל כאילו אין קובץ שירות (service worker).
פרמטרים
-
handler
התקשרות חזרה פונקציה שמחזירה את Promise שמובילה לתשובה.