워크박스 라우팅

서비스 워커는 페이지에 대한 네트워크 요청을 가로챌 수 있습니다. 캐시된 콘텐츠, 네트워크의 콘텐츠 또는 서비스 워커에서 생성된 콘텐츠로 브라우저에 응답할 수 있습니다.

workbox-routing는 응답을 제공하는 다른 함수로 이러한 요청을 쉽게 '라우팅'할 수 있는 모듈입니다.

라우팅 수행 방법

네트워크 요청으로 인해 서비스 워커 가져오기 이벤트가 ��생하면 workbox-routing는 제공된 경로와 핸들러를 사용하여 요청에 응답하려고 시도합니다.

작업 상자 라우팅 다이어그램

위의 주요 내용은 다음과 같습니다.

  • 요청 메서드는 중요합니다. 기본적으로 경로는 GET 요청에 등록됩니다. 다른 유형의 요청을 가로채려면 메서드를 지정해야 합니다.

  • 경로 등록 순서가 중요합니다. 요청을 처리할 수 있는 여러 경로가 등록된 경우 먼저 등록된 경로가 요청에 응답하는 데 사용됩니다.

경로를 등록하는 데는 콜백, 정규 표현식, 경로 인스턴스를 사용하는 등 몇 가지 방법이 있습니다.

경로 일치 및 처리

작업 상자의 '경로'는 두 가지 기능일 뿐입니다. 경로가 요청과 일치하는지 확인하는 '일치' 함수와 요청을 처리하고 응답으로 응답해야 하는 '처리' 함수입니다.

Workbox에는 일치 및 처리를 자동으로 수행하는 몇 가지 도우미가 제공되지만, 다른 동작이 필요한 경우 맞춤 일치 및 핸들러 함수를 작성하는 것이 가장 좋습니다.

일치 콜백 함수에는 ExtendableEvent, Request, 진실한 값을 반환하여 일치시킬 수 있는 URL 객체가 전달됩니다. 간단한 예로 다음과 같이 특정 URL과 일치시킬 수 있습니다.

const matchCb = ({url, request, event}) => {
  return url.pathname === '/special/url';
};

대부분의 사용 사례는 url 또는 request 검사 / 테스트를 통해 처리할 수 있습니다.

핸들러 콜백 함수에는 'match' 함수에서 반환된 값인 params 값과 함께 동일한 ExtendableEvent, Request, URL 객체가 제공됩니다.

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로 확인되는 프로미스를 반환해야 합니다. 이 예시에서는 asyncawait를 사용합니다. 내부적으로 반환 Response 값은 프로미스로 래핑됩니다.

이러한 콜백은 다음과 같이 등록할 수 있습니다.

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb);

유일한 제한사항은 'match' 콜백은 동기식으로 진실한 값을 반환해야 하며 비동기 작업을 실행할 수 없다는 것입니다. 그 이유는 Router가 가져오기 이벤트에 동기식으로 응답하거나 다른 가져오기 이벤트로 넘어갈 수 있도록 허용해야 하기 때문입니다.

일반적으로 'handler' 콜백은 다음과 같이 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의 하위 집합으로 응답하도록 제한하려면 allowlistdenylist 옵션을 사용하여 이 경로와 일치하는 페이지를 제한하면 됩니다.

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이 allowlistdenylist에 모두 있는 경우 denylist가 우선한다는 것입니다.

기본 핸들러 설정

경로와 일치하지 않는 요청에 대해 '핸들러'를 제공하려면 기본 핸들러를 설정할 수 있습니다.

import {setDefaultHandler} from 'workbox-routing';

setDefaultHandler(({url, event, params}) => {
  // ...
});

캐치 핸들러 설정

경로에서 오류가 발생하는 경우 catch 핸들러를 설정하여 단계적으로 캡처하고 성능이 저하될 수 있습니다.

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를 통해 처리 중인 URL을 보여주는 workbox-routing의 로그를 사용하여 요청 흐름을 파악할 수 있어야 합니다.

로그 라우팅

더 자세한 정보가 필요한 경우 로그 수준을 debug로 설정하여 라우터에서 처리하지 않은 요청의 로그를 볼 수 있습니다. 로그 수준 설정에 관한 자세한 내용은 디버깅 가이드를 참고하세요.

디버그 메시지 및 로그 라우팅 메시지

고급 사용법

작업 상자 라우터에 요청이 주어지는 시점을 더 세부적으로 관리하려면 라우터를 사용하여 요청에 응답하려고 할 때마다 자체 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를 사용하면 브라우저[탐색 요청]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests와 일치하는 workbox-routing.Route를 쉽게 만들 수 있습니다.

https://fetch.spec.whatwg.org/#concept-request-mode|modenavigate로 설정된 수신 요청만 일치합니다.

필요한 경우 denylistallowlist 매개변수 중 하나 또는 둘 다를 사용하여 이 경로를 탐색 요청의 하위 집합에만 적용할 수 있습니다.

속성

  • 생성자

    void

    denylistallowlist가 모두 제공되면 denylist가 우선 적용되며 요청은 이 경로와 일치하지 않습니다.

    allowlistdenylist의 정규 표현식은 요청된 URL의 연결된 [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를 사용하지 마세요. 사용하지 않으면 사용자가 사이트를 탐색할 때 지연이 발생할 수 있습니다.

    constructor 함수는 다음과 같습니다.

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

  • catchHandler

    RouteHandlerObject 선택사항

  • method

    HTTPMethod

  • setCatchHandler

    void

    setCatchHandler 함수는 다음과 같습니다.

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

    • handler

      응답으로 확인되는 프로미스를 반환하는 콜백 함수

NavigationRouteMatchOptions

속성

  • 허용 목록

    RegExp[] 선택사항

  • 차단 목록

    RegExp[] 선택사항

RegExpRoute

RegExpRoute를 사용하면 workbox-routing.Route 기반의 정규 표현식을 쉽게 만들 수 있습니다.

동일한 출처 요청의 경우 RegExp는 URL의 일부와만 일치하면 됩니다. 서드 파티 서버에 대한 요청의 경우 URL의 시작 부분과 일치하는 RegExp를 정의해야 합니다.

속성

  • 생성자

    void

    정규 표현식에 [캡처 그룹]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

      프로미스를 반환하여 응답을 반환하는 콜백 함수입니다.

    • method

      HTTPMethod 선택사항

  • catchHandler

    RouteHandlerObject 선택사항

  • method

    HTTPMethod

  • setCatchHandler

    void

    setCatchHandler 함수는 다음과 같습니다.

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

    • handler

      응답으로 확인되는 프로미스를 반환하는 콜백 함수

Route

Route는 'match' 및 'handler'라는 콜백 함수 쌍으로 구성됩니다. 'match' 콜백은 가능한 경우 거짓이 아닌 값을 반환하여 요청을 '처리'하는 데 경로를 사용해야 하는지 판단합니다. 일치하는 항목이 있으면 '핸들러' 콜백이 호출되며 Response로 확인되는 프로미스를 반환해야 합니다.

속성

  • 생성자

    void

    Route 클래스의 생성자입니다.

    constructor 함수는 다음과 같습니다.

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

    • 잘못된 값을 반환하여 경로가 지정된 fetch 이벤트와 일치하는지 확인하는 콜백 함수입니다.

    • handler

      응답으로 확인되는 프로미스를 반환하는 콜백 함수입니다.

    • method

      HTTPMethod 선택사항

  • catchHandler

    RouteHandlerObject 선택사항

  • method

    HTTPMethod

  • setCatchHandler

    void

    setCatchHandler 함수는 다음과 같습니다.

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

    • handler

      응답으로 확인되는 프로미스를 반환하는 콜백 함수

Router

라우터는 하나 이상의 workbox-routing.Route를 사용하여 FetchEvent를 처리하고 일치하는 경로가 있으면 Response로 응답하는 데 사용될 수 있습니다.

지정된 요청과 일치하는 경로가 없으면 라우터는 '기본' 핸들러가 정의되어 있으면 이 핸들러를 사용합니다.

일치하는 경로에서 오류가 발생하면 라우터는 'catch' 핸들러(문제를 적절하게 처리하고 요청으로 응답하도록 정의된 경우)를 사용합니다.

요청이 여러 경로와 일치하면 가장 먼저 등록된 경로를 사용하여 요청에 응답합니다.

속성

  • 생성자

    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

      객체

      routeparams 속성이 있는 객체입니다. 일치하는 경로가 있으면 채워지고 그렇지 않으면 undefined됩니다.

  • handleRequest

    void

    라우팅 규칙을 FetchEvent 객체에 적용하여 적절한 경로의 핸들러에서 응답을 가져옵니다.

    handleRequest 함수는 다음과 같습니다.

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

    • 옵션

      객체

      • event

        ExtendableEvent

        요청을 트리거한 이벤트입니다.

      • 요청

        요청

        처리할 요청입니다.

    • returns

      프로미스<응답>

      등록된 경로가 요청을 처리할 수 있는 경우 프로미스가 반환됩니다. 일치하는 경로가 없고 defaultHandler도 없으면 undefined이 반환됩니다.

  • registerRoute

    void

    라우터에 경로를 등록합니다.

    registerRoute 함수는 다음과 같습니다.

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

    • 경로

      등록할 경로입니다.

  • setCatchHandler

    void

    요청을 처리하는 동안 경로에서 오류가 발생하면 이 handler가 호출되고 응답을 제공할 기회가 주어집니다.

    setCatchHandler 함수는 다음과 같습니다.

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

    • handler

      프로미스를 반환하여 응답을 반환하는 콜백 함수입니다.

  • setDefaultHandler

    void

    수신 요청과 명시적으로 일치하는 경로가 없을 때 호출되는 기본 handler를 정의합니다.

    각 HTTP 메서드 ('GET', 'POST' 등)는 고유한 기본 핸들러를 가져옵니다.

    기본 핸들러가 없으면 일치하지 않는 요청이 서비스 워커가 없는 것처럼 네트워크에서 이루어집니다.

    setDefaultHandler 함수는 다음과 같습니다.

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

    • handler

      프로미스를 반환하여 응답을 반환하는 콜백 함수입니다.

    • 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를 호출합니다.

매개변수

  • capture

    string | RegExp | RouteMatchCallback | Route

    캡처 매개변수가 Route이면 다른 모든 인수는 무시됩니다.

  • handler

    RouteHandler 선택사항

  • method

    HTTPMethod 선택사항

반환 값

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

요청을 처리하는 동안 경로에서 오류가 발생하면 이 handler가 호출되고 응답을 제공할 기회가 주어집니다.

매개변수

  • handler

    프로미스를 반환하여 응답을 반환하는 콜백 함수입니다.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

수신 요청과 명시적으로 일치하는 경로가 없을 때 호출되는 기본 handler를 정의합니다.

기본 핸들러가 없으면 일치하지 않는 요청이 서비스 워커가 없는 것처럼 네트워크에서 이루어집니다.

매개변수

  • handler

    프로미스를 반환하여 응답을 반환하는 콜백 함수입니다.