| [[JavaScript| 관련 문서 | |||
| {{{#!wiki style="margin: 0 -10px -5px; min-height: calc(1.5em + 5px)" {{{#!folding [ 펼치기 · 접기 ] {{{#!wiki style="margin: -5px -1px -11px" | <colbgcolor=#f7df1e,#f7df1e><colcolor=#000,#000> 관련 문서 | 표준(TC39 · 브라우저 전쟁) · Vanilla JS · AJAX · JSFuck · 상태관리 라이브러리 · JSON · CSS-in-JS | |
| 문법 | this · undefined | ||
| 표준 라이브러리 및 API | 표준 내장 객체 · Fetch API · Web Cryptography API | ||
| 구현체 | <bgcolor=#f7df1e,#f7df1e> 엔진 | V8 · SpiderMonkey · JavaScriptCore · 헤르메스 · Boa | |
| <bgcolor=#f7df1e,#f7df1e> 런타임 | Node.js · Deno · Bun · workerd | ||
| 패키지 관리자 | npm · Bun | ||
| 파생 언어 | TypeScript · CoffeeScript · ActionScript · AssemblyScript · elm · PureScript · ReasonML · ReScript | ||
| 관련 인물 | 브랜든 아이크 | ||
| 기타 | JavaScript npm 마비 사태 | }}}}}}}}} | |
1. 개요
WHATWG가 관리하는 Fetch 표준의 일부로, HTTP 프로토콜을 통한 자원 요청을 위한 JavaScript 인터페이스 스펙이다.WHATWG Fetch는 웹 브라우저 수준의 모든 리소스 fetch 및 그 동작을 규정하는 방대한 스펙이고, 본 문서에서 설명하는 건 섹션 5의 Fetch API 뿐이다.
2. 구성
2.1. Headers
HTTP/헤더 데이터를 나타내는 인터페이스다. HTTP 헤더 특성상 헤더가 중복되는 경우도 있고 표준상 case insensitive하기 때문에 단순한 딕셔너리 타입으로는 표현이 불가능하기 때문.내부 상태 중 하나로 가드가 있는데, 직접 설정할 수는 없고 해당 헤더가 Request에 들어가냐 Response에 들어가냐 등이나 요청 시 CORS 정책 설정에 따라 동작이 달라진다.
2.2. Body
HTTP 요청의 body 데이터 및 해당 저수준 데이터에 접근할 수 있는 API. 스펙에 인터페이스는 아니고 믹스인으로 정의되어 있는데, 때문에 Request랑 Response 두 클래스에서 모두 사용할 수 있다.가장 간단하게는
.body 프로퍼티로 ReadableStream을 얻을 수 있다. 이외에도 ArrayBuffer를 주는 .arrayBuffer(), Blob을 주는 .blob(), Uint8Array를 주는 .bytes() 등 실제 body 데이터를 적당한 타입으로 접근할 수 있는 메서드가 존재하며, 심지어 버퍼를 UTF-8로 파싱해 주는 .text(), application/x-www-form-urlencoded를 파싱해 주는 .formData(), JSON을 파싱해 주는 .json() 등의 메서드가 내장되어 있다.body 데이터를 읽을 시 stream이 이미 닫혔거나
disturbed 상태라면 읽기가 실패한다. 때문에 보통의 요청은 body를 두 번 이상 읽는게 불가능하다.[1]2.3. Request
HTTP 요청 데이터를 나타내는 인터페이스다.2018년부터 AbortSignal API를 지원하기 시작했다.https://fetch.spec.whatwg.org/
2.4. RequestInit
HTTP 요청을 보낼 때 값을 설정하기 위해 사용하는 dictionary 타입이다.2.5. DeferredRequestInit
후술할 fetchLater 요청을 보낼 때 값을 설정하기 위해 사용하는 dictionary 타입이다. 현재는activateafter 하나밖에 없다.2.6. Response
HTTP 응답 데이터를 나타내는 인터페이스다.2.7. ResponseInit
HTTP 응답을 보낼 때 값을 설정하기 위해 사용하는 dictionary 타입이다.2.8. fetch
partial interface mixin WindowOrWorkerGlobalScope {
[NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
};전역 스코프에 존재하는 함수. RequestInit을 받아 Response를 돌려주는 Promise를 반환한다.2.9. fetchLater
partial interface Window {
[NewObject, SecureContext] FetchLaterResult fetchLater(RequestInfo input, optional DeferredRequestInit init = {});
};최근 Chromium 팀에 의해 도입된# 표준으로, 브라우저 창이 닫히거나 다른 탭으로 넘어가거나 특정 시간이 지나는 등 일반적으로 예측할 수 없는 브라우저 이벤트가 발생한 직후에 요청을 보내기 위해 사용한다. 해당 콜이 실행되면 Promise 말고 FetchLaterResult를 반환하며, activated 필드로 해당 요청이 실행되었는지 확인할 수 있다. 애초에 JS 쪽으로는 Promise를 넘기지 않기 때문에 fetchLater의 응답을 확인하는 것은 불가능하다.Chrome의 경우 2024년 1월 121 버전부터 시험적으로 추가되기 시작했다.#
3. 의의
실질적으로는 XHR보다 모던한 AJAX 구현을 위한 표준으로 인식되고 있다. XHR이 워낙 복잡하고, 뭣보다 브라우저 이벤트 루프 및 이벤트 시스템에 종속적인 데 반해 fetch는 Promise를 던져주는 등의 대표적인 장점이 있다. 그리고 CORS나 쿠키 핸들링 관련해서 XHR보다 좀더 상세하며, Cache API 등 다른 최신 웹 API와 연동이 가능하다는 점도 있다. 성능 면에서도 장점이 있는데, 응답을 전부 단일 버퍼링하는 XHR과 다르게 최근 지원되는ReadableStream 등 스트림 타입을 건드릴 수 있기 때문에 JS 환경에서 모든 body를 읽어야 하는 상황이 아니라면 성능적 이점이 있다.현재는 완전히 웹 표준이 되었기에, Node.js등 fetch보다도 오래된(...) 환경을 제외하면 새로 만들어지는 런타임 환경은 대부분 fetch를 표준으로 적극적으로 도입하거나 응용하는 편. 가령 Cloudflare Workers는 클라이언트 요청만 아니라 서버리스 function 자체를 하나의 fetch 함수로 추상화하고, 해당 function에 런타임이 표준 Request 객체를 넣어주고 Response 객체를 가져가는 식으로 이루어져 있다.
결국 Node.js도 최신 버전부터는 undici 기반의 네이티브 fetch API가 지원되기에 이르렀다.
4. 런타임별 지원 및 환경별 상세
웬만큼 모던한 대부분의 웹 브라우저는 최소 몇 년은 전부터fetch()를 안정적으로 지원하고 있다. fetchLater()는 Chromium 쪽에서 지원이 활발한 편.Node.js는 2022년부터 undici를 통해
fetch()를 내장 지원하기 시작했다.# 당연하지만 fetchLater()는 미구현 상태이다.#61940workerd의 경우 내장 지원된다.# worker 내부에 있는 서버리스 function이
fetch 형태로 되어 있고, 그 안에서도 fetch 호출이 가능한데, 이는 subrequest로 처리된다.Next.js 등 웹 프레임워크 단에서도 별도의 fetch를 제공하는 경우가 존재한다.