👷‍♂️

service workerでリクエストをバイパスするときの書き方

に公開

/admin以下はキャッシュを見ないでそのままバイパスしたいとき

以下のようにservice workerの中でfetchするより

self.addEventListener("fetch", (event) => {
  event.respondWith((async () => {
    const url = new URL(event.request.url);
    if (url.pathname.startsWith("/admin")) {
      // /admin 以下はバイパス
      return fetch(event.request);
    }
    const response = await caches.match(event.request);
    return response || fetch(event.request);
  })());
});

以下のようにそのまま何もしないでreturnしたほうがいい

self.addEventListener("fetch", (event) => {
  const url = new URL(event.request.url);
  if (url.pathname.startsWith("/admin")) {
    // /admin 以下はバイパス
    return;
  }
  event.respondWith(
    caches.match(event.request).then((response) => {
      return response || fetch(event.request);
    }),
  );
});

というのもfetchを経由すると, Sec-Fetch-*ヘッダが付与され
Sec-Fetch-Dest: document ではなく
Sec-Fetch-Dest: empty としてリクエストしてしまいます

挙動が変わらないページなら良いのですが、apacheのmod_auth_openidcのように
OIDC認証が通ってない場合はログイン画面に飛ばすはずが(例えばGoogleならレスポンスコード302でhttps://accounts.google.com/o/oauth2/v2/auth... に飛ばす)
Sec-Fetch-Dest: emptyとしてリクエストすると401としか返さないようになります

なので注意しましょうという小ネタでした
serviceWorkerを経由するURLの方が少ない場合はscopeを指定して細かく制御する方が良いかも
navigator.serviceWorker.register("/sw.js", { scope: "/index.html" );

Discussion