توجيه صندوق العمل

يمكن لعامل الخدمة اعتراض طلبات الشبكة لإحدى الصفحات. وقد يستجيب للمتصفّح من خلال تقديم محتوى مخزَّن مؤقتًا أو محتوى من الشبكة أو محتوى تم إنشاؤه في مشغّل الخدمات.

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)=> {...}

  • catchHandler

    RouteHandlerObject اختيارية

  • المعالج
  • مطابقة
  • method

    HTTPMethod

  • setCatchHandler

    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 اختياري

  • catchHandler

    RouteHandlerObject اختيارية

  • المعالج
  • مطابقة
  • method

    HTTPMethod

  • setCatchHandler

    void

    تبدو الدالة setCatchHandler على النحو التالي:

    (handler: RouteHandler)=> {...}

    • المعالج

      دالة رد اتصال تقوم بإرجاع حل الوعد إلى استجابة

Route

تتكوّن السمة Route من دالّتَي معاودة الاتصال، وهما "match" و "المعالج". تحدد معاودة الاتصال "مطابقة" ما إذا كان يجب استخدام المسار "لمعالجة" أحد الطلبات من خلال عرض قيمة غير مزيّفة إذا كان ذلك ممكنًا. يتم استدعاء استدعاء "المعالج" عند وجود تطابق ويجب أن يعرض الوعد الذي يتم حله إلى Response.

أماكن إقامة

  • الدالة الإنشائية

    void

    منشئ فئة المسار

    تبدو الدالة constructor على النحو التالي:

    (match: RouteMatchCallback,handler: RouteHandler,method?: HTTPMethod)=> {...}

    • مطابقة

      هي دالة لرد الاتصال تحدِّد ما إذا كان المسار يتطابق مع حدث fetch معيّن من خلال عرض قيمة غير مزورة.

    • المعالج

      دالة معاودة اتصال تقوم بإرجاع حل الوعد إلى استجابة.

    • method

      HTTPMethod اختياري

  • catchHandler

    RouteHandlerObject اختيارية

  • المعالج
  • مطابقة
  • method

    HTTPMethod

  • setCatchHandler

    void

    تبدو الدالة setCatchHandler على النحو التالي:

    (handler: RouteHandler)=> {...}

    • المعالج

      دالة رد اتصال تقوم بإرجاع حل الوعد إلى استجابة

Router

يمكن استخدام جهاز التوجيه لمعالجة FetchEvent باستخدام workbox-routing.Route واحد أو أكثر، والاستجابة باستخدام Response في حال توفّر مسار مطابق.

وفي حالة عدم تطابق أي مسار مع طلب معين، سيستخدم جهاز التوجيه المعالج "الافتراضي" في حالة تحديد واحد.

إذا عرض المسار المطابق خطأ، فسيستخدم جهاز التوجيه معالج "التقاط" إذا تم تعريفه للتعامل بشكل أنيق مع المشكلات والاستجابة للطلب.

وإذا تطابق طلب مع مسارات متعدّدة، سيتم استخدام أول مسار مسجَّل للاستجابة للطلب.

أماكن إقامة

  • الدالة الإنشائية

    void

    يقوم بتهيئة جهاز توجيه جديد.

    تبدو الدالة constructor على النحو التالي:

    ()=> {...}

  • مسارات

    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)=> {...}

    • الخيارات

      كائن

      • حدث

        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.

المَعلمات

  • الحصول على معلومات حول

    إذا كانت معلمة الالتقاط هي Route، سيتم تجاهل جميع الوسيطات الأخرى.

  • المعالج

    RouteHandler اختيارية

  • method

    HTTPMethod اختياري

المرتجعات

  • تمثّل هذه السمة Route الذي تم إنشاؤه.

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

إذا حدث خطأ في أحد المسارات أثناء معالجة أحد الطلبات، سيتم الاتصال بـ handler هذا ومنحه فرصة لتقديم رد.

المَعلمات

  • المعالج

    دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

حدِّد مسار handler تلقائي يتم استدعاؤه عندما لا تتطابق أي مسارات مع الطلب الوارد بشكل صريح.

وبدون معالج تلقائي، ستنتقل الطلبات غير المطابقة إلى الشبكة كما لو لم يكن هناك مشغّل خدمات.

المَعلمات

  • المعالج

    دالة معاودة اتصال تعرض الوعد ناتجًا عن استجابة.