워크박스 라우팅

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

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

    문자열|RegExp|RouteMatchCallback|경로

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

  • handler

    RouteHandler 선택사항

  • method

    HTTPMethod 선택사항

반환 값

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

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

매개변수

  • handler

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

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

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

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

매개변수

  • handler

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