Request: cache 속성

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2017.

Request 인터페이스의 cache 읽기 전용 속성에는 요청의 캐시 모드가 포함되어 있습니다. 요청이 브라우저의 HTTP 캐싱과 상호 작용하는 방식을 제어합니다.

RequestCache 값입니다. 사용 가능한 값은 다음과 같습니다.

  • default — 브라우저는 HTTP 캐시에서 일치하는 요청을 찾습니다.

    • 일치하는 항목이 있고 새 항목이면, 캐시에서 반환됩니다.
    • 일치하는 항목이 있지만 오래된 항목이면, 브라우저는 원격 서버에 조건부 요청을 합니다. 서버가 리소스가 변경되지 않았다고 표시하면, 캐시에서 리소스가 반환됩니다. 그렇지 않으면 리소스가 서버에서 다운로드되고 캐시가 업데이트됩니다.
    • 일치하는 항목이 없으면, 브라우저는 정상 요청을 하고 다운로드된 리소스로 캐시를 업데이트합니다.
  • no-store - 브라우저는 캐시를 먼저 살펴보지 않고 원격 서버에서 리소스를 가져오며, 다운로드된 리소스로 캐시를 업데이트하지 않습니다.

  • reload - 브라우저는 캐시를 먼저 살펴보지 않고 원격 서버에서 리소스를 가져오며, 그 다음으로 다운로드된 리소스로 캐시를 업데이트합니다.

  • no-cache - 브라우저는 HTTP 캐시에서 일치하는 요청을 찾습니다.

    • 새 항목이든 오래된 항목이든 일치하는 항목이 있으면, 브라우저는 원격 서버에 조건부 요청을 보냅니다. 서버가 리소스가 변경되지 않았다고 표시하면, 캐시에서 리소스가 반환됩니다. 그렇지 않으면 리소스가 서버에서 다운로드되고 캐시가 업데이트됩니다.
    • 일치하는 항목이 없으면, 브라우저는 정상 요청을 하고 다운로드된 리소스로 캐시를 업데이트합니다.
  • force-cache - 브라우저는 HTTP 캐시에서 일치하는 요청을 찾습니다.

    • 새 항목이든 오래된 항목이든 일치하는 항목이 있으면, 캐시에서 반환됩니다.
    • 일치하는 항목이 없으면, 브라우저는 정상 요청을 하고 다운로드된 리소스로 캐시를 업데이트합니다.
  • only-if-cached — 브라우저는 HTTP 캐시에서 일치하는 요청을 찾습니다.

    • 새 항목이든 오래된 항목이든 일치하는 항목이 있으면, 캐시에서 반환됩니다.
    • 일치하는 항목이 없으면, 브라우저는 504 Gateway timeout 상태로 응답합니다.

    "only-if-cached" 모드는 요청 mode"same-origin"인 경우에만 사용할 수 있습니다. 캐시된 리다이렉션은 요청의 redirect 속성이 "follow"이고 리다이렉션이 "same-origin" 모드를 위반하지 않는 경우에만 허용됩니다.

예제

js
// 캐시를 완전히 우회하기 위해 캐시 버스팅 기능이 있는 리소스를 다운로드합니다.
fetch("some.json", { cache: "no-store" }).then((response) => {
  /* 응답 사용 */
});

// 캐시 버스팅 기능을 사용하여 리소스를 다운로드하지만, 다운로드된 리소스로 HTTP 캐시를 업데이트합니다.
fetch("some.json", { cache: "reload" }).then((response) => {
  /* 응답 사용 */
});

// 올바른 ETag와 Date 헤더를 전송하고 If-Modified-Since와 If-None-Match 요청 헤더를 적절하게 처리하는 제대로 구성된 서버를 다룰 때 캐시 버스팅이 있는 리소스를 다운로드하면 유효성 검사에 의존하여 새로운 응답을 보장할 수 있습니다.
fetch("some.json", { cache: "no-cache" }).then((response) => {
  /* 응답 사용 */
});

// 경제성을 염두에 둔 리소스를 다운로드합니다! 가능한 많은 대역폭을 절약하기 위해 오래되었지만 캐시된 응답을 선호합니다.
fetch("some.json", { cache: "force-cache" }).then((response) => {
  /* 응답 사용 */
});

// 클라이언트 수준에서 stale-while-revalidate로 유지됩니다.
// 오래된 응답이라도 캐시된 응답을 선호하지만, 너무 오래된 경우 업데이트합니다.
// 더 나은 메모리 정리를 위해 AbortController와 signal를 사용합니다.
// 실제로 이것은 값을 변경해야 하므로 컨트롤러에 대한 경로와 참조를 취하는 함수가 될 것입니다.
let controller = new AbortController();
fetch("some.json", {
  cache: "only-if-cached",
  mode: "same-origin",
  signal: controller.signal,
})
  .catch((e) =>
    e instanceof TypeError && e.message === "Failed to fetch"
      ? { status: 504 } // 크롬에서의 해결 방법: TypeError로 실패
      : Promise.reject(e),
  )
  .then((res) => {
    if (res.status === 504) {
      controller.abort();
      controller = new AbortController();
      return fetch("some.json", {
        cache: "force-cache",
        mode: "same-origin",
        signal: controller.signal,
      });
    }
    const date = res.headers.get("date"),
      dt = date ? new Date(date).getTime() : 0;
    if (dt < Date.now() - 86_400_000) {
      // 24시간이 지난 경우
      controller.abort();
      controller = new AbortController();
      return fetch("some.json", {
        cache: "reload",
        mode: "same-origin",
        signal: controller.signal,
      });
    }

    // 기타 가능한 조건
    if (dt < Date.now() - 300_000)
      // 5분 이상 지난 경우
      fetch("some.json", { cache: "no-cache", mode: "same-origin" }); // 취소 혹은 반환 값이 없습니다.
    return res;
  })
  .then((response) => {
    /* (아마도 오래된) 응답 사용 */
  })
  .catch((error) => {
    /* AbortError/DOMError 혹은 TypeError일 수 있습니다. */
  });

명세서

Specification
Fetch Standard
# ref-for-dom-request-cache②

브라우저 호환성

BCD tables only load in the browser

같이 보기