يمكن لعامل الخدمة اعتراض طلبات الشبكة لإحدى الصفحات. وقد يستجيب للمتصفّح من خلال تقديم محتوى مخزَّن مؤقتًا أو محتوى من الشبكة أو محتوى تم إنشاؤه في مشغّل الخدمات.
workbox-routing
هي وحدة تسهّل "توجيه" هذه الطلبات إلى دوال مختلفة تقدّم ردودًا.
كيفية تنفيذ التوجيه
عندما يتسبب طلب الشبكة في حدوث حدث جلب لدى مشغّل الخدمات، سيحاول workbox-routing
الاستجابة للطلب باستخدام المسارات والمعالجات التي تم توفيرها.
وفي ما يلي النقاط الأساسية التي يجب أخذها في الاعتبار مما سبق:
طريقة الطلب مهمة. يتم تلقائيًا تسجيل المسارات لطلبات
GET
. إذا كنت تريد اعتراض أنواع أخرى من الطلبات، عليك تحديد الطريقة.يُعد ترتيب تسجيل المسار مهمًا. فإذا تم تسجيل عدة مسارات يمكنها معالجة أحد الطلبات، فسيتم استخدام المسار الذي تم تسجيله أولاً للاستجابة للطلب.
هناك بضع طرق لتسجيل مسار: يمكنك استخدام معاودة الاتصال أو التعبيرات العادية أو مثيلات المسار.
مطابقة المسارات والتعامل معها في المسارات
لا يزيد "المسار" في مربع العمل عن أكثر من دالتين: دالة "متطابقة" لتحديد ما إذا كان المسار يجب أن يتطابق مع طلب ووظيفة "معالجة"، والتي ينبغي أن تتولى معالجة الطلب والاستجابة للطلب.
يأتي Workbox مزودًا ببعض أدوات المساعدة التي ستقوم بالمطابقة والتعامل نيابة عنك، ولكن إذا وجدت نفسك في أي وقت تريد سلوكًا مختلفًا، فإن كتابة مطابقة مخصصة ودالة معالج هي الخيار الأفضل.
يتم تمرير
دالة معاودة الاتصال بمطابقة
إلى ExtendableEvent
وRequest
وURL
كائن يمكنك مطابقتها من خلال عرض قيمة صحيحة. على سبيل المثال، يمكنك المطابقة مع
عنوان URL معين مثل:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
يمكن تغطية معظم حالات الاستخدام من خلال فحص / اختبار url
أو request
.
سيتم منح
دالة استدعاء المعالج
نفس
الكائن 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,
});
};
يجب أن يعرض معالجك وعدًا يتم حلّه إلى Response
. في هذا المثال، نستخدم async
وawait
.
من غير المرجّح أن تتضمّن هذه القيمة أيًّا من القيم المرتجعة من Response
.
يمكنك تسجيل عمليات معاودة الاتصال هذه كما يلي:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
القيد الوحيد هو أن معاودة الاتصال "مطابقة" يجب أن تعرض بشكل متزامن قيمة صادقة، ولا يمكنك تنفيذ أي عمل غير متزامن. والسبب في ذلك هو أنّه يجب أن تستجيب دالة Router
بشكل متزامن لحدث الجلب أو تسمح بوصولها إلى أحداث استرجاع أخرى.
في العادة، يستخدم معاودة الاتصال "المعالج" إحدى الاستراتيجيات المتوفرة من خلال workbox-strategies على النحو التالي:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
في هذه الصفحة، سنركّز على workbox-routing
، ولكن يمكنك الاطّلاع على مزيد من المعلومات حول هذه الاستراتيجيات حول استراتيجيات إطار العمل.
كيفية تسجيل مسار التعبير العادي
من الممارسات الشائعة استخدام تعبير عادي بدلاً من معاودة الاتصال "match". يُسهّل 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
.
ضبط معالج تلقائي
إذا كنت تريد توفير "معالج" للطلبات التي لا تتطابق مع أي مسار، يمكنك تعيين معالِج افتراضي.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
ضبط معالج التقاط
في حالة حدوث خطأ في أي من مساراتك، يمكنك التقاط الصور وخفض مستوى أدائها بطريقة آمنة من خلال تعيين معالج الإمساك.
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 التي تتم معالجتها من خلال 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
تسهِّل واجهة Navigation Route إنشاء
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 المطلوب.ملاحظة: يمكن تقييم التعبير العادي هذا مقابل كل عنوان URL مقصود أثناء عملية التنقل. تجنَّب استخدام RegExps المعقّدة، وإلا قد يلاحظ المستخدمون تأخيرات عند التنقّل في موقعك الإلكتروني.
تبدو الدالة
constructor
على النحو التالي:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.
-
NavigationRouteMatchOptions اختيارية
-
-
RouteHandlerObject اختيارية
-
HTTPMethod
-
void
تبدو الدالة
setCatchHandler
على النحو التالي:(handler: RouteHandler) => {...}
-
دالة رد اتصال تقوم بإرجاع حل الوعد إلى استجابة
-
NavigationRouteMatchOptions
أماكن إقامة
-
التعبير العادي[] اختياري
-
التعبير العادي[] اختياري
RegExpRoute
يسهّل RegExpRoute إنشاء تعبير عادي استنادًا إلى workbox-routing.Route
.
وبالنسبة إلى طلبات المصدر نفسه، يحتاج RegExp فقط إلى مطابقة جزء من عنوان URL. بالنسبة إلى الطلبات المقدَّمة إلى الخوادم التابعة لجهات خارجية، عليك تحديد تعبير عادي يتطابق مع بداية عنوان URL.
أماكن إقامة
-
الدالة الإنشائية
void
إذا كان التعبير العادي يحتوي على [capture groups]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
، سيتم تمرير القيم التي تم التقاطها إلى وسيطةparams
workbox-routing~handlerCallback
.تبدو الدالة
constructor
على النحو التالي:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
التعبير العادي المطلوب مطابقته مع عناوين URL.
-
المعالج
دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.
-
method
HTTPMethod اختياري
-
returns
-
-
catchHandler
RouteHandlerObject اختيارية
-
المعالج
-
مطابقة
-
method
HTTPMethod
-
setCatchHandler
void
تبدو الدالة
setCatchHandler
على النحو التالي:(handler: RouteHandler) => {...}
-
المعالج
دالة رد اتصال تقوم بإرجاع حل الوعد إلى استجابة
-
Route
تتكوّن السمة Route
من دالّتَي معاودة الاتصال، وهما "match" و "المعالج".
تحدد معاودة الاتصال "مطابقة" ما إذا كان يجب استخدام المسار "لمعالجة" أحد الطلبات من خلال عرض قيمة غير مزيّفة إذا كان ذلك ممكنًا. يتم استدعاء استدعاء "المعالج" عند وجود تطابق ويجب أن يعرض الوعد الذي يتم حله إلى Response
.
أماكن إقامة
-
الدالة الإنشائية
void
منشئ فئة المسار
تبدو الدالة
constructor
على النحو التالي:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
مطابقة
هي دالة لرد الاتصال تحدِّد ما إذا كان المسار يتطابق مع حدث
fetch
معيّن من خلال عرض قيمة غير مزورة. -
المعالج
دالة معاودة اتصال تقوم بإرجاع حل الوعد إلى استجابة.
-
method
HTTPMethod اختياري
-
returns
-
-
catchHandler
RouteHandlerObject اختيارية
-
المعالج
-
مطابقة
-
method
HTTPMethod
-
setCatchHandler
void
تبدو الدالة
setCatchHandler
على النحو التالي:(handler: RouteHandler) => {...}
-
المعالج
دالة رد اتصال تقوم بإرجاع حل الوعد إلى استجابة
-
Router
يمكن استخدام جهاز التوجيه لمعالجة FetchEvent
باستخدام workbox-routing.Route
واحد أو أكثر، والاستجابة باستخدام Response
في حال توفّر مسار مطابق.
وفي حالة عدم تطابق أي مسار مع طلب معين، سيستخدم جهاز التوجيه المعالج "الافتراضي" في حالة تحديد واحد.
إذا عرض المسار المطابق خطأ، فسيستخدم جهاز التوجيه معالج "التقاط" إذا تم تعريفه للتعامل بشكل أنيق مع المشكلات والاستجابة للطلب.
وإذا تطابق طلب مع مسارات متعدّدة، سيتم استخدام أول مسار مسجَّل للاستجابة للطلب.
أماكن إقامة
-
الدالة الإنشائية
void
يقوم بتهيئة جهاز توجيه جديد.
تبدو الدالة
constructor
على النحو التالي:() => {...}
-
returns
-
-
مسارات
Map<HTTPMethodRoute[]>
-
addCacheListener
void
تعمل هذه السياسة على إضافة أداة معالجة حدث الرسائل إلى عناوين URL التي ستخزّنها مؤقتًا من النافذة. ويكون ذلك مفيدًا لتخزين الموارد التي تم تحميلها على الصفحة في ذاكرة التخزين المؤقت قبل بدء عامل الخدمة في التحكّم فيها.
يجب أن يكون تنسيق بيانات الرسالة المرسلة من النافذة على النحو التالي. حيث قد تتكون مصفوفة
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) => {...}
-
الخيارات
-
returns
عنصر
عنصر مع السمتَين
route
وparams
. تتم تعبئتها في حال العثور على مسار مطابق أوundefined
بطريقة أخرى.
-
-
handleRequest
void
طبِّق قواعد التوجيه على كائن FetchEvent للحصول على استجابة من معالج "مسار" مناسب.
تبدو الدالة
handleRequest
على النحو التالي:(options: object) => {...}
-
الخيارات
عنصر
-
event
ExtendableEvent
الحدث الذي أدى إلى الطلب.
-
طلب
الطلب
الطلب الذي ستتم معالجته.
-
-
returns
وعد<الرد>
يظهر الوعد إذا كان بإمكان المسار المسجّل معالجة الطلب. إذا لم يكن هناك مسار مطابق ولم يكن هناك
defaultHandler
، يتم عرضundefined
.
-
-
registerRoute
void
تسجيل مسار باستخدام جهاز التوجيه.
تبدو الدالة
registerRoute
على النحو التالي:(route: Route) => {...}
-
مسار
مسار التسجيل.
-
-
setCatchHandler
void
إذا حدث خطأ في أحد المسارات أثناء معالجة أحد الطلبات، سيتم الاتصال بـ
handler
هذا ومنحه فرصة لتقديم رد.تبدو الدالة
setCatchHandler
على النحو التالي:(handler: RouteHandler) => {...}
-
المعالج
دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.
-
-
setDefaultHandler
void
حدِّد مسار
handler
تلقائي يتم استدعاؤه عندما لا تتطابق أي مسارات مع الطلب الوارد بشكل صريح.تحصل كل طريقة HTTP ("GET" و"POST" وغير ذلك) على المعالج الافتراضي الخاص بها.
وبدون معالج تلقائي، ستنتقل الطلبات غير المطابقة إلى الشبكة كما لو لم يكن هناك مشغّل خدمات.
تبدو الدالة
setDefaultHandler
على النحو التالي:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
المعالج
دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.
-
method
HTTPMethod اختياري
-
-
unregisterRoute
void
إلغاء تسجيل مسار مع جهاز التوجيه.
تبدو الدالة
unregisterRoute
على النحو التالي:(route: Route) => {...}
-
مسار
المسار المراد إلغاء التسجيل فيه
-
الطُرق
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
يمكنك بسهولة تسجيل RegExp أو سلسلة أو وظيفة من خلال استراتيجية تخزين مؤقت على مثيل جهاز التوجيه المفرد.
ستعمل هذه الطريقة على إنشاء مسار لك إذا لزم الأمر
والاتصال بـ workbox-routing.Router#registerRoute
.
المَعلمات
-
الحصول على معلومات حول
سلسلة | RegExp | RouteMatchCallback | المسار
إذا كانت معلمة الالتقاط هي
Route
، سيتم تجاهل جميع الوسيطات الأخرى. -
المعالج
RouteHandler اختيارية
-
method
HTTPMethod اختياري
المرتجعات
-
تمثّل هذه السمة
Route
الذي تم إنشاؤه.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
إذا حدث خطأ في أحد المسارات أثناء معالجة أحد الطلبات، سيتم الاتصال بـ handler
هذا ومنحه فرصة لتقديم رد.
المَعلمات
-
المعالج
دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
حدِّد مسار handler
تلقائي يتم استدعاؤه عندما لا تتطابق أي مسارات مع الطلب الوارد بشكل صريح.
وبدون معالج تلقائي، ستنتقل الطلبات غير المطابقة إلى الشبكة كما لو لم يكن هناك مشغّل خدمات.
المَعلمات
-
المعالج
دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.