مسیریابی جعبه کاری

یک سرویس دهنده می تواند درخواست های شبکه را برای یک صفحه رهگیری کند. ممکن است با محتوای ذخیره شده، محتوای شبکه یا محتوای تولید شده در سرویس دهنده به مرورگر پاسخ دهد.

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 باید به طور همزمان به رویداد واکشی پاسخ دهد یا اجازه دهد تا به رویدادهای دیگر واکشی بیفتد.

معمولاً فراخوانی «هندلر» از یکی از استراتژی‌های ارائه‌شده توسط جعبه‌کار-استراتژی‌هایی مانند زیر استفاده می‌کند:

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') استفاده کنیم. 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);

تنها چیزی که باید به آن توجه داشت این است که اگر URL در هر دو لیست allowlist و denylist باشد، 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

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 بخش‌هایی از URL درخواستی.

    توجه : این RegExps ممکن است در طول یک پیمایش در برابر هر URL مقصد ارزیابی شود. از استفاده از RegExps پیچیده خودداری کنید، در غیر این صورت کاربران شما ممکن است در هنگام پیمایش سایت شما با تاخیر مواجه شوند.

    تابع constructor به صورت زیر است:

    (handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}

    • کنترل کننده

      یک تابع فراخوانی که یک Promise را برمی‌گرداند که منجر به یک پاسخ می‌شود.

    • گزینه ها

      NavigationRouteMatchOptions اختیاری است

  • catchHandler

    RouteHandlerObject اختیاری است

  • کنترل کننده
  • مطابقت دادن
  • روش

    روش HTTPM

  • setCatchHandler

    باطل

    تابع setCatchHandler به شکل زیر است:

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

    • کنترل کننده

      یک تابع callback که یک Promise Resolving را به یک Response برمی گرداند

NavigationRouteMatchOptions

خواص

  • لیست مجاز

    RegExp[] اختیاری است

  • انکار کننده

    RegExp[] اختیاری است

RegExpRoute

RegExpRoute ایجاد یک عبارت معمولی مبتنی بر workbox-routing.Route را آسان می کند.

برای درخواست‌های یکسان، RegExp فقط باید با بخشی از URL مطابقت داشته باشد. برای درخواست‌ها علیه سرورهای شخص ثالث، باید یک RegExp تعریف کنید که با شروع URL مطابقت داشته باشد.

خواص

  • سازنده

    باطل

    اگر عبارت منظم حاوی [گروه‌های گرفتن] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references باشد، مقادیر گرفته شده به workbox-routing~handlerCallback ارسال می‌شوند. workbox-routing~handlerCallback argument params .

    تابع constructor به صورت زیر است:

    (regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}

    • regExp

      RegExp

      عبارت منظم برای مطابقت با URL ها.

    • کنترل کننده

      یک تابع فراخوانی که یک Promise را برمی‌گرداند که منجر به یک پاسخ می‌شود.

    • روش

      روش HTTPM اختیاری است

  • catchHandler

    RouteHandlerObject اختیاری است

  • کنترل کننده
  • مطابقت دادن
  • روش

    روش HTTPM

  • setCatchHandler

    باطل

    تابع setCatchHandler به شکل زیر است:

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

    • کنترل کننده

      یک تابع callback که یک Promise Resolving را به یک Response برمی گرداند

Route

یک Route شامل یک جفت توابع پاسخ به تماس، "Match" و "Handler" است. پاسخ به تماس "Match" تعیین می کند که آیا مسیری باید برای "پرداخت" یک درخواست با برگرداندن یک مقدار غیر نادرست در صورت امکان استفاده شود یا خیر. فراخوانی «هندلر» زمانی فراخوانی می‌شود که تطابق وجود داشته باشد و باید یک Promise را که به یک Response حل می‌شود برگرداند.

خواص

  • سازنده

    باطل

    سازنده برای کلاس مسیر.

    تابع constructor به صورت زیر است:

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

    • مطابقت دادن

      یک تابع فراخوانی که تعیین می کند آیا مسیر با یک رویداد fetch مشخص مطابقت دارد یا خیر.

    • کنترل کننده

      یک تابع callback که یک Promise Resolving را به یک Response برمی گرداند.

    • روش

      روش HTTPM اختیاری است

  • catchHandler

    RouteHandlerObject اختیاری است

  • کنترل کننده
  • مطابقت دادن
  • روش

    روش HTTPM

  • setCatchHandler

    باطل

    تابع setCatchHandler به شکل زیر است:

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

    • کنترل کننده

      یک تابع callback که یک Promise Resolving را به یک Response برمی گرداند

Router

روتر را می توان برای پردازش یک FetchEvent با استفاده از یک یا چند workbox-routing.Route استفاده کرد و در صورت وجود مسیر منطبق، با یک Response پاسخ می دهد.

اگر هیچ مسیری با یک درخواست داده شده مطابقت نداشته باشد، در صورت تعریف، روتر از یک کنترل کننده "پیش فرض" استفاده می کند.

اگر مسیر منطبق با خطا مواجه شود، روتر از یک کنترل کننده "catch" استفاده می کند، در صورتی که تعریف شده باشد که به راحتی با مسائل برخورد کند و با یک درخواست پاسخ دهد.

اگر درخواستی با چندین مسیر مطابقت داشته باشد، از اولین مسیر ثبت شده برای پاسخ به درخواست استفاده خواهد شد.

خواص

  • سازنده

    باطل

    یک روتر جدید را راه اندازی می کند.

    تابع constructor به صورت زیر است:

    () => {...}

  • مسیرها

    نقشه<HTTPMethodRoute[]>

  • addCacheListener

    باطل

    یک شنونده رویداد پیام برای نشانی‌های وب به حافظه پنهان از پنجره اضافه می‌کند. این برای ذخیره منابع بارگذاری شده در صفحه قبل از زمانی که سرویس‌کار شروع به کنترل آن کرد، مفید است.

    فرمت داده های پیام ارسال شده از پنجره باید به صورت زیر باشد. جایی که آرایه urlsToCache ممکن است شامل رشته‌های URL یا آرایه‌ای از رشته URL + شی requestInit باشد (همان چیزی که به fetch() ارسال می‌کنید).

    {
      type: 'CACHE_URLS',
      payload: {
        urlsToCache: [
          './script1.js',
          './script2.js',
          ['./script3.js', {mode: 'no-cors'}],
        ],
      },
    }
    

    تابع addCacheListener به شکل زیر است:

    () => {...}

  • افزودن FetchListener

    باطل

    هنگامی که مسیری با درخواست رویداد مطابقت دارد، شنونده رویداد واکشی را اضافه می کند تا به رویدادها پاسخ دهد.

    تابع addFetchListener به شکل زیر است:

    () => {...}

  • findMatchingRoute

    باطل

    یک درخواست و URL (و در صورت تمایل یک رویداد) را در برابر لیست مسیرهای ثبت شده بررسی می کند، و در صورت وجود مطابقت، مسیر مربوطه را به همراه هر پارامتر ایجاد شده توسط مسابقه برمی گرداند.

    تابع findMatchingRoute به شکل زیر است:

    (options: RouteMatchCallbackOptions) => {...}

    • برمی گرداند

      شی

      یک شی با ویژگی های route و params . اگر مسیر منطبقی پیدا شود یا در غیر این صورت undefined باشد، پر می شوند.

  • handleRequest

    باطل

    قوانین مسیریابی را بر روی یک شی FetchEvent اعمال کنید تا یک پاسخ از یک کنترل کننده مسیر مناسب دریافت کنید.

    تابع handleRequest به نظر می رسد:

    (options: object) => {...}

    • گزینه ها

      شی

      • رویداد

        ExtendableEvent

        رویدادی که باعث ایجاد درخواست شد.

      • درخواست کنید

        درخواست کنید

        درخواست رسیدگی.

    • برمی گرداند

      قول<پاسخ>

      اگر یک مسیر ثبت‌شده بتواند درخواست را انجام دهد، یک وعده بازگردانده می‌شود. اگر مسیر منطبقی وجود نداشته باشد و defaultHandler وجود نداشته باشد، undefined برگردانده می‌شود.

  • ثبت مسیر

    باطل

    یک مسیر را با روتر ثبت می کند.

    تابع registerRoute به نظر می رسد:

    (route: Route) => {...}

    • مسیر

      مسیر ثبت نام

  • setCatchHandler

    باطل

    اگر مسیری در هنگام رسیدگی به یک درخواست خطایی ایجاد کند، این handler فراخوانی می شود و فرصتی برای ارائه پاسخ داده می شود.

    تابع setCatchHandler به شکل زیر است:

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

    • کنترل کننده

      یک تابع فراخوانی که یک Promise را برمی‌گرداند که منجر به یک پاسخ می‌شود.

  • setDefaultHandler

    باطل

    یک handler پیش فرض را تعریف کنید که زمانی فراخوانی می شود که هیچ مسیری به طور صریح با درخواست ورودی مطابقت نداشته باشد.

    هر روش HTTP ("GET"، "POST"، و غیره) کنترل کننده پیش فرض خود را دارد.

    بدون کنترل‌کننده پیش‌فرض، درخواست‌های بی‌همتا به‌گونه‌ای در مقابل شبکه قرار می‌گیرند که گویی هیچ سرویس‌دهنده‌ای در آن حضور ندارد.

    تابع setDefaultHandler به شکل زیر است:

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

    • کنترل کننده

      یک تابع فراخوانی که یک Promise را برمی‌گرداند که منجر به یک پاسخ می‌شود.

    • روش

      روش HTTPM اختیاری است

  • لغو ثبت مسیر

    باطل

    یک مسیر را با روتر لغو ثبت می کند.

    تابع unregisterRoute به نظر می رسد:

    (route: Route) => {...}

    • مسیر

      مسیر لغو ثبت نام

روش ها

registerRoute()

workbox-routing.registerRoute(
  capture: string | RegExp | RouteMatchCallback | Route,
  handler?: RouteHandler,
  method?: HTTPMethod,
)

به راحتی یک RegExp، رشته یا تابع را با یک استراتژی کش در یک نمونه روتر تک تنی ثبت کنید.

این روش در صورت نیاز یک Route برای شما ایجاد می کند و workbox-routing.Router#registerRoute را فراخوانی می کند.

پارامترها

  • گرفتن

    رشته | RegExp | RouteMatchCallback | مسیر

    اگر پارامتر ضبط یک Route باشد، همه آرگومان های دیگر نادیده گرفته می شوند.

  • کنترل کننده

    RouteHandler اختیاری است

  • روش

    روش HTTPM اختیاری است

برمی گرداند

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

اگر یک مسیر در هنگام رسیدگی به یک درخواست خطایی ایجاد کند، این handler فراخوانی می شود و فرصتی برای ارائه پاسخ داده می شود.

پارامترها

  • کنترل کننده

    یک تابع فراخوانی که یک Promise را برمی‌گرداند که منجر به یک پاسخ می‌شود.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

یک handler پیش فرض را تعریف کنید که زمانی فراخوانی می شود که هیچ مسیری به طور صریح با درخواست ورودی مطابقت نداشته باشد.

بدون کنترل‌کننده پیش‌فرض، درخواست‌های بی‌تطابق بر خلاف شبکه خواهند رفت، گویی هیچ سرویس‌دهنده‌ای در آن حضور ندارد.

پارامترها

  • کنترل کننده

    یک تابع فراخوانی که یک Promise را برمی‌گرداند که منجر به یک پاسخ می‌شود.