패치

현행 표준 — 마지막 갱신

참여:
GitHub whatwg/fetch (새 이슈, 열린 이슈)
Matrix에서 채팅
커밋:
GitHub whatwg/fetch/commits
이 커밋 기준 스냅샷
@fetchstandard
테스트:
web-platform-tests fetch/ (진행 중 작업)
번역 (비규범적):
日本語
简体中文
한국어

요약

패치 표준은 요청, 응답, 그리고 이를 연결하는 과정인 패칭을 정의합니다.

목표

이 표준의 목표는 웹 플랫폼 전반에 걸쳐 패칭을 통합하고, 이에 관련된 모든 것에 대해 일관된 처리를 제공하는 것입니다. 여기에는 다음이 포함됩니다:

이를 위해 HTTP `Origin` 헤더 의미를 원래 The Web Origin Concept에서 정의했던 것보다 대체합니다. [ORIGIN]

1. 서문

상위 관점에서 리소스를 패칭하는 것은 꽤 단순한 작업입니다. 요청이 들어가고, 응답이 나옵니다. 하지만 그 작업의 세부사항은 매우 복잡하며, 예전에는 명확하게 문서화되지 않았고 API마다 다르게 동작했습니다.

수많은 API가 리소스를 패치하는 기능을 제공합니다. 예를 들면 HTML의 imgscript 요소, CSS의 cursorlist-style-image, navigator.sendBeacon()self.importScripts() 같은 JavaScript API들이 있습니다. 패치 표준은 이러한 기능들을 위한 통합된 아키텍처를 제공하여, 리디렉션 및 CORS 프로토콜 등 패칭의 다양한 측면에서 모두 일관성을 갖도록 합니다.

패치 표준은 또한 fetch() JavaScript API를 정의하며, 이는 대부분의 네트워킹 기능을 비교적 낮은 추상화 수준에서 노출합니다.

2. 인프라스트럭처

이 명세는 Infra 표준에 의존합니다. [INFRA]

이 명세는 ABNF, Encoding, HTML, HTTP, MIME Sniffing, Streams, URL, Web IDL, WebSockets의 용어를 사용합니다. [ABNF] [ENCODING] [HTML] [HTTP] [MIMESNIFF] [STREAMS] [URL] [WEBIDL] [WEBSOCKETS]

ABNF는 HTTP에서 확장된 ABNF(특히 #의 추가)와 RFC 7405를 의미합니다. [RFC7405]


인증 정보(Credentials)는 HTTP 쿠키, TLS 클라이언트 인증서, 그리고 인증 항목(HTTP 인증용)입니다. [COOKIES] [TLS] [HTTP]


fetch paramsstruct로, fetch 알고리즘에서 부기 용도로 사용됩니다. 다음과 같은 항목을 가집니다:

request
request.
요청 본문 청크 길이 처리 (기본값 null)
process request end-of-body (기본값 null)
process early hints response (기본값 null)
process response (기본값 null)
process response end-of-body (기본값 null)
process response consume body (기본값 null)
Null 또는 알고리즘.
task destination (기본값 null)
Null, global object, 또는 parallel queue.
cross-origin isolated capability (기본값 false)
불리언 값.
controller (기본값 새 fetch controller)
fetch controller.
timing info
fetch timing info.
preloaded response candidate (기본값 null)
Null, "pending", 또는 response.

fetch controllerstruct로, fetch 호출자가 시작 후 특정 작업을 수행할 수 있도록 합니다. 다음과 같은 항목을 가집니다:

state (기본값 "ongoing")
"ongoing", "terminated", 또는 "aborted"
full timing info (기본값 null)
Null 또는 fetch timing info.
report timing steps (기본값 null)
Null 또는 global object를 인자로 받는 알고리즘.
serialized abort reason (기본값 null)
Null 또는 Record (StructuredSerialize 결과).
next manual redirect steps (기본값 null)
Null 또는 인자를 받지 않는 알고리즘.

특정 fetch controller controller에 대해 타이밍 보고(report timing)를 하려면, global object global을 받아 다음을 실행합니다:

  1. Assert: controllerreport timing steps가 null이 아님을 확인합니다.

  2. controllerreport timing stepsglobal과 함께 호출합니다.

특정 fetch controller controller에 대해 다음 수동 리디렉트 처리를 하려면:

  1. Assert: controllernext manual redirect steps가 null이 아님을 확인합니다.

  2. controllernext manual redirect steps를 호출합니다.

fetch controller controller에 대해 전체 타이밍 정보 추출을 하려면:

  1. Assert: controllerfull timing info가 null이 아님을 확인합니다.

  2. controllerfull timing info를 반환합니다.

특정 fetch controller controller에 대해 선택적 error와 함께 abort 하려면:

  1. controllerstate를 "aborted"로 설정합니다.

  2. fallbackError를 "AbortError" DOMException으로 둡니다.

  3. error가 주어지지 않았다면 fallbackError로 설정합니다.

  4. serializedErrorStructuredSerialize(error)로 둡니다. 예외가 발생하면 serializedErrorStructuredSerialize(fallbackError)로 둡니다.

  5. controllerserialized abort reasonserializedError로 설정합니다.

null 또는 Record abortReasonrealm realm이 주어졌을 때 serialize된 abort reason 역직렬화는 다음과 같습니다:

  1. fallbackError를 "AbortError" DOMException으로 둡니다.

  2. deserializedErrorfallbackError로 둡니다.

  3. abortReason이 null이 아니면, deserializedErrorStructuredDeserialize(abortReason, realm)로 둡니다. 예외가 발생하거나 undefined를 반환하면 deserializedErrorfallbackError로 둡니다.

  4. deserializedError를 반환합니다.

fetch controller controller종료(terminate)하려면, controllerstate를 "terminated"로 설정합니다.

fetch params fetchParams는, 그 controllerstate가 "aborted"일 때 중단(aborted) 상태입니다.

fetch params fetchParams는, 그 controllerstate가 "aborted" 또는 "terminated"일 때 취소(canceled) 상태입니다.

fetch timing infostruct로, Resource TimingNavigation Timing에 필요한 타이밍 정보를 유지합니다. 다음의 항목을 가집니다: [RESOURCE-TIMING] [NAVIGATION-TIMING]

start time (기본값 0)
redirect start time (기본값 0)
redirect end time (기본값 0)
post-redirect start time (기본값 0)
final service worker start time (기본값 0)
final network-request start time (기본값 0)
first interim network-response start time (기본값 0)
final network-response start time (기본값 0)
end time (기본값 0)
DOMHighResTimeStamp.
final connection timing info (기본값 null)
Null 또는 connection timing info.
server-timing headers (기본값 « »)
문자열의 list.
render-blocking (기본값 false)
불리언 값.

response body infostruct로, Resource TimingNavigation Timing에 필요한 정보를 유지합니다. 다음의 항목을 가집니다: [RESOURCE-TIMING] [NAVIGATION-TIMING]

encoded size (기본값 0)
decoded size (기본값 0)
숫자.
content type (기본값 빈 문자열)
ASCII 문자열.
content encoding (기본값 빈 문자열)
ASCII 문자열.

fetch timing info timingInfo가 주어졌을 때 불투명 타이밍 정보 생성은, timingInfostart timepost-redirect start timetimingInfostart time인 새로운 fetch timing info를 반환합니다.

알고리즘 algorithm, global object 또는 parallel queue taskDestination이 주어졌을 때 fetch 태스크 큐잉(queue a fetch task)은 다음과 같이 실행합니다:

  1. taskDestinationparallel queue라면, enqueue algorithmtaskDestination에 추가합니다.

  2. 그렇지 않으면, 글로벌 태스크(global task)networking task sourcetaskDestinationalgorithm으로 큐잉합니다.


정수 직렬화(serialize an integer)란, 정수를 가능한 가장 짧은 십진수 문자열로 표현하는 것입니다.

이 부분은 Infra에서 더 자세한 알고리즘으로 교체될 예정입니다. infra/201 참고.

2.1. URL

로컬 스킴(local scheme)은 "about", "blob", 또는 "data"입니다.

URL로컬임(is local)은 해당 스킴로컬 스킴일 때입니다.

이 정의는 Referrer Policy에서도 사용됩니다. [REFERRER]

HTTP(S) 스킴은 "http" 또는 "https"입니다.

패치 스킴(fetch scheme)은 "about", "blob", "data", "file", 또는 HTTP(S) 스킴입니다.

HTTP(S) 스킴패치 스킴 역시 HTML에서 사용됩니다. [HTML]

2.2. HTTP

패칭은 HTTP에만 국한되지 않지만, HTTP에서 여러 개념을 차용하여 다른 방식(예: data URL)으로 획득한 리소스에도 적용합니다.

HTTP 탭 또는 공백(HTTP tab or space)은 U+0009 TAB 또는 U+0020 SPACE입니다.

HTTP 공백(HTTP whitespace)은 U+000A LF, U+000D CR, 또는 HTTP 탭 또는 공백입니다.

HTTP 공백은 HTTP 헤더 맥락 이외에서 재사용되는 특정 구조에만 유용합니다(예: MIME 타입). HTTP 헤더 값에는 HTTP 탭 또는 공백 사용을 권장하며, 그 외 맥락에서는 ASCII 공백을 권장합니다. ASCII 공백과 달리 U+000C FF는 제외됩니다.

HTTP 줄바꿈 바이트(HTTP newline byte)는 0x0A (LF) 또는 0x0D (CR)입니다.

HTTP 탭 또는 공백 바이트(HTTP tab or space byte)는 0x09 (HT) 또는 0x20 (SP)입니다.

HTTP 공백 바이트(HTTP whitespace byte)HTTP 줄바꿈 바이트 또는 HTTP 탭 또는 공백 바이트입니다.

HTTP 따옴표 문자열 수집(collect an HTTP quoted string) 을 하려면 문자열(string) input, 위치 변수(position variable) position, 선택적 불리언 extract-value (기본값 false)가 주어졌을 때 다음을 수행합니다:

  1. positionStartposition으로 둡니다.

  2. value를 빈 문자열로 둡니다.

  3. Assert: inputposition에 있는 코드 포인트가 U+0022 (")임을 확인합니다.

  4. position을 1만큼 증가시킵니다.

  5. 다음이 참인 동안:

    1. U+0022 (") 또는 U+005C (\)가 아닌 코드 포인트 시퀀스 수집 결과를 input, position으로부터 value에 추가합니다.

    2. positioninput의 끝을 지난 경우, break합니다.

    3. quoteOrBackslashinputposition에 있는 코드 포인트로 둡니다.

    4. position을 1만큼 증가시킵니다.

    5. quoteOrBackslash가 U+005C (\)이면:

      1. positioninput의 끝을 지난 경우 U+005C (\)를 value에 추가하고 break합니다.

      2. inputposition에 있는 코드 포인트value에 추가합니다.

      3. position을 1만큼 증가시킵니다.

    6. 그 외의 경우:

      1. Assert: quoteOrBackslash가 U+0022 (")임을 확인합니다.

      2. Break.

  6. extract-value가 true라면 value를 반환합니다.

  7. inputpositionStart부터 position까지(포함)의 코드 포인트들을 반환합니다.

입력 출력 extract-value가 true일 때의 출력 최종 위치 변수
""\" ""\" "\" 2
""Hello" World" ""Hello"" "Hello" 7
""Hello \\ World\""" ""Hello \\ World\""" "Hello \ World"" 18

이 예시에서 위치 변수는 항상 0에서 시작합니다.

2.2.1. 메서드

메서드(method)바이트 시퀀스로, method 토큰 생성식을 만족하는 것입니다.

CORS-안전 목록 메서드(CORS-safelisted method)메서드 중 `GET`, `HEAD`, 또는 `POST`인 것입니다.

금지된 메서드(forbidden method)메서드바이트 대소문자 구분 없이 `CONNECT`, `TRACE`, 또는 `TRACK`와 일치하는 것입니다. [HTTPVERBSEC1], [HTTPVERBSEC2], [HTTPVERBSEC3]

메서드 정규화(normalize)를 하려면, 메서드바이트 대소문자 구분 없이 `DELETE`, `GET`, `HEAD`, `OPTIONS`, `POST`, 또는 `PUT`와 일치한다면, 대문자 바이트(byte-uppercase)로 변환합니다.

정규화는 과거와의 호환성 및 API 간의 일관성을 위해 수행되며, 메서드는 실제로 "대소문자 구분"입니다.

`patch`를 사용하면 `405 Method Not Allowed`가 발생할 가능성이 높습니다. 반면 `PATCH`는 성공 가능성이 훨씬 더 높습니다.

메서드에는 제한이 없습니다. `CHICKEN`도 완벽하게 허용됩니다(그리고 `CHECKIN`의 오타가 아닙니다). 정규화되는 것 외에는 대소문자 제한도 없습니다. `Egg`나 `eGg`도 괜찮지만, 일관성을 위해 대문자를 권장합니다.

2.2.2. 헤더

HTTP는 일반적으로 헤더를 "필드(field)" 또는 "헤더 필드(header field)"라고 부릅니다. 웹 플랫폼에서는 더 구어체인 "헤더(header)"라는 용어를 사용합니다. [HTTP]

헤더 목록(header list)리스트(list)이며, 0개 이상의 헤더(header)를 포함합니다. 처음에는 « »입니다.

헤더 목록은 본질적으로 특수한 멀티맵: 키-값 쌍의 순서 있는 리스트로, 키가 중복될 수 있습니다. `Set-Cookie`를 제외한 헤더는 클라이언트 측 JavaScript에 노출될 때 항상 합쳐지므로, 구현체는 `Set-Cookie` 헤더용 별도 데이터 구조만 지원하면 더 효율적인 표현을 선택할 수 있습니다.

구조화 필드 값 가져오기(get a structured field value) 를 하려면 헤더 이름 name과 문자열 type헤더 목록 list에서 주어졌을 때 다음 단계를 실행합니다. 결과는 null 또는 구조화 필드 값(structured field value)입니다.

  1. Assert: type은 "dictionary", "list", 또는 "item" 중 하나입니다.

  2. value헤더 목록에서 name을 가져온 결과로 둡니다.

  3. value가 null이면 null을 반환합니다.

  4. result구조화 필드 파싱(parsing structured fields)의 결과로 둡니다. input_stringvalue, header_typetype입니다.

  5. 파싱에 실패했다면 null을 반환합니다.

  6. result를 반환합니다.

구조화 필드 값 가져오기해당 헤더가 존재하지 않는 것과 이 구조화 필드 값으로 파싱에 실패한 것을 의도적으로 구분하지 않습니다. 이는 웹 플랫폼 전반에서 일관된 처리를 보장합니다.

구조화 필드 값 설정(set a structured field value) 을 하려면 튜플(tuple) (헤더 이름 name, 구조화 필드 값 structuredValue)과 헤더 목록 list가 주어집니다:

  1. serializedValue구조화 필드 직렬화(serializing structured fields) 알고리즘을 structuredValue에 적용한 결과로 둡니다.

  2. Set (name, serializedValue) 를 list에 적용합니다.

구조화 필드 값은 HTTP가(결국) 흥미롭고 효율적으로 직렬화할 수 있는 객체로 정의되어 있습니다. 현재 Fetch는 헤더 값바이트 시퀀스로 지원하므로, 이 객체들은 직렬화를 통해서만 헤더 목록에 설정할 수 있고, 파싱을 통해서만 헤더 목록에서 얻을 수 있습니다. 앞으로는 객체 상태가 끝까지 유지될 수도 있습니다. [RFC9651]


헤더 목록 list헤더를 포함(contains)하는지 여부는 헤더 이름 namelist포함헤더name바이트 대소문자 구분 없이 name과 일치하는 것이 있는지로 판단합니다.

가져오기(get)헤더 이름 name헤더 목록 list가 주어졌을 때 다음 단계를 실행합니다. 결과는 null 또는 헤더 값입니다.

  1. listname을 포함하지 않으면 null을 반환합니다.

  2. list에서 헤더name바이트 대소문자 구분 없이 name과 일치하는 모든 을 0x2C 0x20(쉼표+공백)으로 구분하여 순서대로 반환합니다.

가져오기, 디코드 및 분할(get, decode, and split)헤더 이름 name헤더 목록 list가 주어졌을 때 다음 단계를 실행합니다. 결과는 null 또는 리스트 ( 문자열(string) )입니다.

  1. valuename을 가져온 결과로 둡니다.

  2. value가 null이면 null을 반환합니다.

  3. get, decode, and splitvalue에 적용한 결과를 반환합니다.

다음은 get, decode, and split이 실제로 어떻게 동작하는지, name 인자가 `A`일 때의 예시입니다:

헤더(네트워크 상) 출력
A: nosniff,
« "nosniff", "" »
A: nosniff
B: sniff
A:
A:
B: sniff
« "" »
B: sniff
null
A: text/html;", x/x
« "text/html;", x/x" »
A: text/html;"
A: x/x
A: x/x;test="hi",y/y
« "x/x;test="hi"", "y/y" »
A: x/x;test="hi"
C: **bingo**
A: y/y
A: x / x,,,1
« "x / x", "", "", "1" »
A: x / x
A: ,
A: 1
A: "1,2", 3
« ""1,2"", "3" »
A: "1,2"
D: 4
A: 3

get, decode, and split헤더 값(header value) value에 대해 실행하려면 다음 단계를 따릅니다. 반환 값은 문자열 리스트(list of strings)입니다.

  1. inputisomorphic decoding value 결과로 둡니다.

  2. position위치 변수(position variable)로, input의 시작 위치로 지정합니다.

  3. values문자열 리스트(list of strings)로, 처음에는 « »로 둡니다.

  4. temporaryValue를 빈 문자열로 둡니다.

  5. 다음이 참인 동안 반복합니다:

    1. U+0022 (") 또는 U+002C (,)가 아닌 코드 포인트 시퀀스 수집 결과를 input, position으로부터 temporaryValue에 추가합니다.

      이 결과는 빈 문자열일 수도 있습니다.

    2. positioninput의 끝을 지나지 않았고, position 위치의 코드 포인트가 U+0022 (")이면:

      1. temporaryValueHTTP 따옴표 문자열 수집 결과를 input, position으로부터 추가합니다.

      2. position이 끝을 지나지 않았다면 continue합니다.
    3. temporaryValue의 시작과 끝에서 HTTP 탭 또는 공백을 모두 제거합니다.

    4. Append temporaryValuevalues에 추가합니다.

    5. temporaryValue를 빈 문자열로 설정합니다.

    6. positioninput의 끝을 지났다면 values를 반환합니다.

    7. Assert: inputposition 위치의 코드 포인트가 U+002C (,)임을 확인합니다.

    8. position을 1만큼 증가시킵니다.

특정 허용된 호출지(blessed call sites)를 제외하고, 위 알고리즘을 직접 호출하지 않아야 합니다. 대신 get, decode, and split을 사용하세요.

append헤더(header) (name, value)를 헤더 목록(header list) list에 추가하는 알고리즘입니다:

  1. listname을 포함하면, name을 첫 번째 해당 헤더name으로 설정합니다.

    이렇게 하면 list에 이미 존재하는 헤더name의 대소문자가 재사용됩니다. 여러 개가 일치하면 헤더name은 모두 동일합니다.

  2. Append (name, value)를 list에 추가합니다.

delete헤더 이름(header name) name헤더 목록(header list) list에서 제거하는 알고리즘입니다. 이때 헤더name바이트 대소문자 구분 없이 name과 일치하는 모든 헤더를 list에서 제거합니다.

set헤더(header) (name, value)를 헤더 목록(header list) list에 설정하는 방법입니다:

  1. listname을 포함하면, 첫 번째 해당 헤더(header)값(value)value로 설정하고, 나머지 해당 헤더들은 제거한다.

  2. 그렇지 않으면, append (name, value)를 list에 추가합니다.

combine헤더(header) (name, value)를 헤더 목록(header list) list에 결합하는 방법입니다:

  1. listname을 포함하면, 첫 번째 해당 헤더value 뒤에 0x2C 0x20(쉼표+공백), value를 순서대로 이어붙입니다.

  2. 그렇지 않으면, append (name, value)를 list에 추가합니다.

combineXMLHttpRequestWebSocket 프로토콜 핸드셰이크에서 사용됩니다.

헤더 이름을 정렬된 소문자 집합으로 변환(convert header names to a sorted-lowercase set)하려면, 리스트(list) headerNames가 주어졌을 때 다음 단계를 따릅니다. 반환값은 순서 있는 집합(ordered set)헤더 이름(header name)입니다.

  1. headerNamesSet을 새로운 순서 있는 집합으로 둡니다.

  2. name에 대해, 바이트 소문자화(byte-lowercasing) nameheaderNamesSetappend합니다.

  3. 오름차순 정렬headerNamesSet바이트 비교(byte less than)로 적용한 결과를 반환합니다.

sort and combine헤더 목록(header list) list를 입력받아, 다음 단계를 실행합니다. 반환값은 헤더 목록(header list)입니다.

  1. headers헤더 목록(header list)으로 둡니다.

  2. names헤더 이름을 정렬된 소문자 집합으로 변환한 결과로 둡니다. 이때 list헤더들의 이름을 사용합니다.

  3. name에 대해:

    1. name이 `set-cookie`라면:

      1. valueslist에서 헤더name바이트 대소문자 구분 없이 name과 일치하는 모든 의 리스트로 둡니다.

      2. value에 대해 Append (name, value)를 headers에 추가합니다.

    2. 그 외의 경우:

      1. valuelist에서 name을 가져온 결과로 둡니다.

      2. Assert: value가 null이 아님을 확인합니다.

      3. Append (name, value)를 headers에 추가합니다.

  4. headers를 반환합니다.


헤더(header)튜플(tuple)로, 이름(name) (헤더 이름)과 값(value) (헤더 값)으로 구성됩니다.

헤더 이름(header name)바이트 시퀀스로, field-name 토큰 생성식을 만족합니다.

헤더 값(header value)바이트 시퀀스로, 다음 조건을 모두 만족해야 합니다:

헤더 값의 정의는 field-value 토큰 생성식을 따르지 않는 것이, 배포된 콘텐츠와 호환되지 않기 때문입니다.

헤더 값 정규화(normalize)바이트 시퀀스 potentialValue에서 선행 및 후행 HTTP 공백 바이트를 제거하는 것입니다.


헤더 (name, value) 가 CORS-안전 목록 요청 헤더(CORS-safelisted request-header)인지 판단하려면 다음 단계를 실행합니다:

  1. value길이가 128을 초과하면 false를 반환합니다.

  2. 바이트 소문자화(Byte-lowercase)name에 따라 분기합니다:

    `accept`

    valueCORS-비안전 요청 헤더 바이트가 있으면 false를 반환합니다.

    `accept-language`
    `content-language`

    value에 0x30 (0)~0x39 (9), 0x41 (A)~0x5A (Z), 0x61 (a)~0x7A (z), 0x20 (SP), 0x2A (*), 0x2C (,), 0x2D (-), 0x2E (.), 0x3B (;), 0x3D (=)에 속하지 않는 바이트가 있으면 false를 반환합니다.

    `content-type`
    1. valueCORS-비안전 요청 헤더 바이트가 있으면 false를 반환합니다.

    2. mimeType파싱(parsing)등가 디코딩(isomorphic decoding) value 결과로 둡니다.

    3. mimeType이 실패(failure)라면 false를 반환합니다.

    4. mimeTypeessence가 "application/x-www-form-urlencoded", "multipart/form-data", 또는 "text/plain"이 아니면 false를 반환합니다.

    이는 MIME 타입 추출(extract a MIME type) 알고리즘을 사용하지 않습니다. 해당 알고리즘은 관대하며, 서버가 이를 구현해야 한다고 기대하지 않기 때문입니다.

    MIME 타입 추출을 사용할 경우 아래 요청은 CORS 프리플라이트 없이 처리되고, 서버의 단순 파서는 요청 본문을 JSON으로 처리할 수 있습니다:

    fetch("https://victim.example/naïve-endpoint", {
      method: "POST",
      headers: [
        ["Content-Type", "application/json"],
        ["Content-Type", "text/plain"]
      ],
      credentials: "include",
      body: JSON.stringify(exerciseForTheReader)
    });
    
    `range`
    1. rangeValue단일 range 헤더 값 파싱(parsing a single range header value)value와 false를 넘긴 결과로 둡니다.

    2. rangeValue가 실패(failure)면 false를 반환합니다.

    3. rangeValue[0]이 null이면 false를 반환합니다.

      웹 브라우저는 `bytes=-500`와 같은 range를 내보내지 않으므로 이 알고리즘은 그런 경우를 safelist하지 않습니다.

    기타

    false를 반환합니다.

  3. true를 반환합니다.

`Content-Type` 헤더 safelist에는 제한적 예외가 있습니다. 자세한 내용은 CORS 프로토콜 예외를 참고하세요.

CORS-비안전 요청 헤더 바이트(CORS-unsafe request-header byte)는 바이트 byte가 다음 중 하나에 해당할 때입니다:

CORS-비안전 요청 헤더 이름(CORS-unsafe request-header names)헤더 목록 headers에 대해 다음과 같이 결정합니다:

  1. unsafeNames를 새 리스트로 둡니다.

  2. potentiallyUnsafeNames를 새 리스트로 둡니다.

  3. safelistValueSize를 0으로 둡니다.

  4. headersheader에 대해:

    1. headerCORS-안전 목록 요청 헤더가 아니면, append headernameunsafeNames에 추가합니다.

    2. 그 밖의 경우, headernamepotentiallyUnsafeNames에 추가하고, safelistValueSizeheadervalue길이만큼 더합니다.

  5. safelistValueSize가 1024를 초과하면 potentiallyUnsafeNamesnameappendunsafeNames에 추가합니다.

  6. 헤더 이름을 정렬된 소문자 집합으로 변환unsafeNames를 반환합니다.

CORS non-wildcard 요청 헤더 이름(CORS non-wildcard request-header name)헤더 이름바이트 대소문자 구분 없이 `Authorization`와 일치하는 것입니다.

특권 no-CORS 요청 헤더 이름(privileged no-CORS request-header name)헤더 이름바이트 대소문자 구분 없이 다음 중 하나와 일치하는 것입니다:

이들은 특권 API에서 설정할 수 있으며, 관련 요청 객체가 복사될 때는 보존되지만, 권한이 없는 API가 요청을 수정하는 경우 제거됩니다.

`Range` 헤더는 주로 다운로드미디어 패치에서 사용됩니다.

특정 요청에 range 헤더 추가를 위한 헬퍼가 제공됩니다.

CORS-안전 목록 응답 헤더 이름(CORS-safelisted response-header name)리스트헤더 이름 list에 대해, 다음 중 하나와 바이트 대소문자 구분 없이 일치하는 것입니다:

no-CORS-안전 목록 요청 헤더 이름(no-CORS-safelisted request-header name)헤더 이름바이트 대소문자 구분 없이 다음 중 하나와 일치하는 것입니다:

헤더 (name, value)가 no-CORS-안전 목록 요청 헤더(no-CORS-safelisted request-header)인지 판단하려면 다음 단계를 실행합니다:

  1. nameno-CORS-안전 목록 요청 헤더 이름이 아니면 false를 반환합니다.

  2. (name, value)가 CORS-안전 목록 요청 헤더인지 여부를 반환합니다.

헤더 (name, value)가 금지된 요청 헤더(forbidden request-header)인지 판단하려면 다음 단계가 true를 반환하면 됩니다:

  1. name이 다음 중 하나와 바이트 대소문자 구분 없이 일치하면:

    true를 반환합니다.

  2. name바이트 소문자화하여, proxy- 또는 sec-으로 시작하면 true를 반환합니다.

  3. name이 다음 중 하나와 바이트 대소문자 구분 없이 일치하면:

    • `X-HTTP-Method`
    • `X-HTTP-Method-Override`
    • `X-Method-Override`

    다음 절차를 실행합니다:

    1. parsedValuesget, decode, and split value의 결과로 둡니다.

    2. parsedValuesmethod에 대해, isomorphic encodingmethod금지된 메서드(forbidden method)라면 true를 반환합니다.

  4. false를 반환합니다.

이 헤더들은 사용자 에이전트가 완전히 제어할 수 있도록 금지됩니다.

헤더 이름이 `Sec-`로 시작하는 경우, 헤더fetch 등 개발자가 헤더를 제어할 수 있는 API에 의해 사용될 때, 새 헤더가 안전하게 도입될 수 있도록 예약되어 있습니다. 예: XMLHttpRequest. [XHR]

`Set-Cookie` 헤더는 의미상 응답 헤더이므로 요청에서는 쓸모가 없습니다. `Set-Cookie` 헤더는 결합(combine)될 수 없으므로, Headers 객체에서 더 복잡하게 처리해야 합니다. 여기서 금지하는 이유는 이 복잡성이 요청으로 새어 나가는 것을 막기 위함입니다.

금지된 응답 헤더 이름(forbidden response-header name)헤더 이름바이트 대소문자 구분 없이 다음 중 하나와 일치하는 것입니다:

요청 본문 헤더 이름(request-body-header name)헤더 이름바이트 대소문자 구분 없이 다음 중 하나와 일치하는 것입니다:


헤더 값 추출(extract header values)헤더(header) header가 주어졌을 때 다음 단계를 실행합니다:

  1. headervalueABNF 기준으로 headername에 대해 파싱에 실패하면 failure를 반환합니다.

  2. headervalueABNF 기준으로 파싱하여 나온 하나 이상의 을 반환합니다.

헤더 목록 값 추출(extract header list values)헤더 이름 name헤더 목록(header list) list가 주어졌을 때 다음 단계를 실행합니다:

  1. listname을 포함하지 않으면 null을 반환합니다.

  2. name에 대한 ABNF가 단일 헤더(header)만 허용하고, listname을 중복 포함하면 failure를 반환합니다.

    다른 오류 처리가 필요하다면, 먼저 원하는 헤더를 추출하세요.

  3. values를 빈 리스트로 둡니다.

  4. listname을 포함하는 모든 헤더(header) header에 대해:

    1. extract헤더 값 추출header에 실행한 결과로 둡니다.

    2. extract가 failure면 failure를 반환합니다.

    3. extract각 값을 순서대로 values에 추가합니다.

  5. values를 반환합니다.

콘텐츠 범위 생성(build a content range)은 정수 rangeStart, 정수 rangeEnd, 정수 fullLength가 주어졌을 때 다음 단계를 실행합니다:

  1. contentRange를 `bytes `로 둡니다.

  2. rangeStart직렬화등가 인코딩(isomorphic encoded) 하여 contentRange에 추가합니다.

  3. 0x2D (-)를 contentRange에 추가합니다.

  4. rangeEnd직렬화등가 인코딩 하여 contentRange에 추가합니다.

  5. 0x2F (/)를 contentRange에 추가합니다.

  6. fullLength직렬화등가 인코딩 하여 contentRange에 추가합니다.

  7. contentRange를 반환합니다.

단일 range 헤더 값 파싱(parse a single range header value)바이트 시퀀스 value와 불리언 allowWhitespace가 주어졌을 때 다음을 실행합니다:

  1. data등가 디코딩(isomorphic decoding) value 결과로 둡니다.

  2. data가 "bytes"로 시작하지 않으면 failure를 반환합니다.

  3. position위치 변수(position variable)로, data의 5번째 코드 포인트 위치로 둡니다.

  4. allowWhitespace가 true라면, HTTP 탭 또는 공백 시퀀스를 data, position에서 수집합니다.

  5. dataposition 위치 코드 포인트가 U+003D (=)가 아니면 failure를 반환합니다.

  6. position을 1만큼 증가시킵니다.

  7. allowWhitespace가 true라면, HTTP 탭 또는 공백 시퀀스를 data, position에서 수집합니다.

  8. rangeStartASCII 숫자(ASCII digits) 시퀀스를 data, position에서 수집한 결과로 둡니다.

  9. rangeStartValuerangeStart가 빈 문자열이 아니면 10진수로 해석한 값, 아니면 null로 둡니다.

  10. allowWhitespace가 true라면, HTTP 탭 또는 공백 시퀀스를 data, position에서 수집합니다.

  11. dataposition 위치 코드 포인트가 U+002D (-)가 아니면 failure를 반환합니다.

  12. position을 1만큼 증가시킵니다.

  13. allowWhitespace가 true라면, HTTP 탭 또는 공백 시퀀스를 data, position에서 수집합니다.

  14. rangeEndASCII 숫자(ASCII digits) 시퀀스를 data, position에서 수집한 결과로 둡니다.

  15. rangeEndValuerangeEnd가 빈 문자열이 아니면 10진수로 해석한 값, 아니면 null로 둡니다.

  16. positiondata의 끝을 지나지 않았다면 failure를 반환합니다.

  17. rangeEndValuerangeStartValue가 모두 null이면 failure를 반환합니다.

  18. rangeStartValuerangeEndValue가 모두 숫자이고, rangeStartValuerangeEndValue보다 크면 failure를 반환합니다.

  19. (rangeStartValue, rangeEndValue)를 반환합니다.

    range 끝이나 시작이 생략될 수 있습니다. 예: `bytes=0-` 또는 `bytes=-500`도 유효한 range입니다.

단일 range 헤더 값 파싱은 허용된 range 헤더 값의 일부만 성공하지만, 미디어 요청이나 다운로드 재개 등에서 사용자 에이전트가 가장 자주 사용하는 형식입니다. 이 range 헤더 값 형식은 range 헤더 추가를 통해 설정할 수 있습니다.


기본 `User-Agent` 값(default `User-Agent` value)구현 정의(implementation-defined) 헤더 값입니다 (`User-Agent` 헤더용).

웹 호환성 문제로 인해, 웹 브라우저는 이 값이 `Mozilla/5.0 (`로 시작하도록 하고, 일반적으로 다른 웹 브라우저를 따라하도록 강하게 권장됩니다.

문서 `Accept` 헤더 값(document `Accept` header value)은 `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8`입니다.

2.2.3. 상태

상태(status)는 0부터 999까지(포함)의 정수입니다.

HTTP/1의 status-code를 이 개념에 매핑할 때의 다양한 경계 사례는 이슈 #1156에서 논의되고 있습니다.

null 본문 상태(null body status)는 101, 103, 204, 205, 304인 상태입니다.

ok 상태(ok status)는 200부터 299까지(포함)의 상태입니다.

리다이렉트 상태(redirect status)는 301, 302, 303, 307, 308인 상태입니다.

2.2.4. 본문

본문(body)은 다음으로 구성됩니다:

복제(clone)본문 body에 대해 실행하려면 다음을 따릅니다:

  1. « out1, out2 »를 teeing body스트림의 결과로 둡니다.

  2. body스트림out1으로 설정합니다.

  3. 나머지 멤버는 body에서 복사하고, 본문스트림out2로 하여 반환합니다.

바이트 시퀀스 bytes본문으로(as a body) 얻으려면, 안전하게 추출(safely extracting) bytes의 결과 중 body를 반환합니다.


점진적으로 읽기(incrementally read)본문(body) body와 알고리즘 processBodyChunk, 알고리즘 processEndOfBody, 알고리즘 processBodyError, 옵션으로 null, parallel queue 또는 global object taskDestination (기본값 null)이 주어졌을 때 다음을 실행합니다. processBodyChunk바이트 시퀀스를 인자로 받는 알고리즘이어야 하며, processEndOfBody는 인자 없이, processBodyError는 예외를 인자로 받는 알고리즘이어야 합니다.

  1. taskDestination이 null이면 새 parallel queue 시작 결과를 taskDestination로 둡니다.

  2. reader리더(getting a reader)body스트림에 대해 구합니다.

    이 동작은 예외를 발생시키지 않습니다.

  3. 점진적 읽기 루프(incrementally-read loop)reader, taskDestination, processBodyChunk, processEndOfBody, processBodyError로 실행합니다.

점진적 읽기 루프(incrementally-read loop)를 실행하려면, ReadableStreamDefaultReader 객체 reader, parallel queue 또는 global object taskDestination, 알고리즘 processBodyChunk, 알고리즘 processEndOfBody, 알고리즘 processBodyError가 주어집니다:

  1. readRequest를 다음 read request로 둡니다:

    chunk steps (chunk)
    1. continueAlgorithm을 null로 둡니다.

    2. chunkUint8Array 객체가 아니라면, continueAlgorithm을 다음 단계로 설정합니다: processBodyErrorTypeError와 함께 실행.

    3. 그 외의 경우:

      1. bytes복사(copy)chunk로 둡니다.

        구현은 이 복사를 피하는 전략을 사용할 것을 강력히 권장합니다.

      2. continueAlgorithm을 다음 단계로 설정합니다:

        1. processBodyChunkbytes로 실행.

        2. 점진적 읽기 루프reader, taskDestination, processBodyChunk, processEndOfBody, processBodyError로 재귀 호출.

    4. fetch 태스크 큐잉continueAlgorithm, taskDestination에 실행합니다.

    close steps
    1. fetch 태스크 큐잉processEndOfBody, taskDestination에 실행합니다.

    error steps (e)
    1. fetch 태스크 큐잉processBodyErroretaskDestination로 실행합니다.

  2. 청크 읽기(Read a chunk)readerreadRequest로 실행합니다.

완전히 읽기(fully read)본문(body) body, 알고리즘 processBody, 알고리즘 processBodyError, 옵션으로 null, parallel queue 또는 global object taskDestination (기본값 null)이 주어졌을 때 다음을 실행합니다. processBody바이트 시퀀스를 인자로 받는 알고리즘이어야 하며, processBodyError는 예외(옵션)를 인자로 받을 수 있는 알고리즘이어야 합니다.

  1. taskDestination이 null이면 새 parallel queue 시작 결과를 taskDestination로 둡니다.

  2. successStepsfetch 태스크 큐잉processBodybytes, taskDestination로 실행하는 알고리즘으로 둡니다.

  3. errorStepsfetch 태스크 큐잉processBodyErrorexception, taskDestination로 실행하는 알고리즘으로 둡니다.

  4. reader리더(getting a reader)body스트림에 대해 구합니다. 예외가 발생하면 errorSteps를 그 예외와 함께 실행하고 종료합니다.

  5. 모든 바이트 읽기(Read all bytes)reader, successSteps, errorSteps로 실행합니다.


타입이 있는 본문(body with type)튜플로, 본문(body) (body)과 타입(type) (헤더 값 또는 null)으로 구성됩니다.


콘텐츠 코딩 처리(handle content codings)codingsbytes가 주어졌을 때 다음 단계를 수행합니다:

  1. codings가 지원되지 않으면 bytes를 반환합니다.

  2. HTTP에서 설명한 대로 codingsbytes를 디코딩한 결과를 반환합니다. 디코딩 중 오류가 발생하면 failure를 반환합니다. [HTTP]

2.2.5. 요청

이 절은 요청이 어떻게 동작하는지 자세히 문서화합니다. 시작하려면 요청 설정을 참고하세요.

fetch의 입력값은 요청(request)입니다.

요청은 연관된 메서드(method)를 가집니다. (method) 별도의 언급이 없으면 `GET`입니다.

리다이렉트 중 HTTP fetch에서 설명된 대로 `GET`으로 변경될 수 있습니다.

요청은 연관된 URL (URL)을 가집니다.

구현은 URL 목록 중 첫 번째 요청URL 목록을 가리키게 만드는 것이 권장됩니다. 이 필드는 Fetch에 연결되는 다른 표준의 편의를 위해 별도로 제공됩니다.

요청은 연관된 로컬 URL 전용 플래그(local-URLs-only flag)를 가집니다. 별도의 언급이 없으면 설정되지 않음(unset)입니다.

요청은 연관된 헤더 목록(header list)을 가집니다. (header list) 별도의 언급이 없으면 « »입니다.

요청은 연관된 unsafe-request 플래그를 가집니다. 별도의 언급이 없으면 설정되지 않음(unset)입니다.

unsafe-request 플래그fetch()XMLHttpRequest와 같은 API에서 설정되어, 지정된 메서드헤더 목록에 따라 CORS-프리플라이트 fetch가 수행됨을 보장합니다. 이는 API가 금지된 메서드금지된 요청 헤더를 허용하지 않는 것과는 별개입니다.

요청은 연관된 본문(body)을 가집니다. (null, 바이트 시퀀스, 또는 body) 별도의 언급이 없으면 null입니다.

바이트 시퀀스안전하게 추출되어 body로 바뀌며, HTTP fetch 중 일부 리다이렉트로 인해 이 값이 null이 될 수도 있습니다.


요청은 연관된 클라이언트(client)를 가집니다. (null 또는 environment settings object)

요청은 연관된 reserved client (null, environment, 또는 environment settings object), 별도의 언급이 없으면 null입니다.

이 필드는 탐색 요청(navigation requests) 및 워커 요청에만 사용되며, 서비스 워커 요청에는 사용되지 않습니다. environment탐색 요청용, environment settings object는 워커 요청용입니다.

요청은 연관된 replaces client id (문자열) 값을 가집니다. 별도의 언급이 없으면 빈 문자열입니다.

이 필드는 탐색 요청에만 사용됩니다. id대상 브라우징 컨텍스트(target browsing context)active documentenvironment settings object입니다.

요청은 연관된 사용자 프롬프트용 traversable(traversable for user prompts)을 가집니다. "no-traversable", "client", 또는 traversable navigable 중 하나입니다. 별도의 언급이 없으면 "client"입니다.

이 필드는 요청과 연관된 UI(예: 인증 프롬프트, 클라이언트 인증서 대화상자 등)를 어디에 표시할지 결정할 때 사용합니다.

"no-traversable"
UI를 표시하지 않음; 보통 요청이 네트워크 오류(network error)로 실패함.
"client"
이 값은 fetch 중에 자동으로 "no-traversable" 또는 traversable navigable로 바뀝니다. 이를 통해 표준에서 요청의 사용자 프롬프트용 traversable을 명시적으로 설정하지 않아도 됩니다.
traversable navigable
표시되는 UI는 해당 traversable navigable을 보여주는 브라우저 인터페이스와 연결됩니다.

요청과 연관된 사용자 인터페이스를 사용자 프롬프트용 traversable에서 표시할 때, 사용자 에이전트는 주소 표시줄에 요청의 현재 URL(current URL)에서 유도된 값을 표시해야 합니다(예: 이전 값, 즉 요청의 시작자 URL에서 유도된 값을 표시하지 않아야 함). 또한, 특히 교차 출처 요청의 경우, 요청의 시작자 콘텐츠를 사용자 프롬프트용 traversable에 표시하지 않도록 해야 합니다. 이러한 프롬프트 뒤에 빈 페이지를 표시하는 것이 좋은 방법입니다. 이를 준수하지 않으면 사용자가 어느 출처가 해당 프롬프트를 유발했는지 혼동할 수 있습니다.

요청은 연관된 불리언 keepalive를 가집니다. 별도의 언급이 없으면 false입니다.

이 값이 true이면 요청이 environment settings object보다 오래 지속될 수 있습니다. 예: navigator.sendBeacon() 및 HTML img 요소가 이 기능을 사용합니다. 이 값이 true인 요청은 추가 처리 요구 사항이 적용됩니다.

요청은 연관된 initiator type을 가집니다. 값은 null, "audio", "beacon", "body", "css", "early-hints", "embed", "fetch", "font", "frame", "iframe", "image", "img", "input", "link", "object", "ping", "script", "track", "video", "xmlhttprequest", 또는 "other" 중 하나입니다. 별도의 언급이 없으면 null입니다. [RESOURCE-TIMING]

요청은 연관된 service-workers mode를 가집니다. 값은 "all" 또는 "none" 중 하나입니다. 별도의 언급이 없으면 "all"입니다.

이 값은 어떤 서비스 워커가 이 fetch에 대해 fetch 이벤트를 받을지 결정합니다.

"all"
해당 서비스 워커가 이 fetch에 대해 fetch 이벤트를 받게 됩니다.
"none"
어떤 서비스 워커도 이 fetch에 대해 이벤트를 받지 않습니다.

요청은 연관된 initiator를 가집니다. 값은 빈 문자열, "download", "imageset", "manifest", "prefetch", "prerender", 또는 "xslt" 중 하나입니다. 별도의 언급이 없으면 빈 문자열입니다.

요청initiator는 현재로서는 다른 명세에서 더 세분화가 필요하지 않아 비교적 단순합니다. 주로 CSP와 혼합 콘텐츠 정의를 돕는 명세 장치입니다. JavaScript에는 노출되지 않습니다. [CSP] [MIX]

대상 타입(destination type)은 다음 중 하나입니다: 빈 문자열, "audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "json", "manifest", "object", "paintworklet", "report", "script", "serviceworker", "sharedworker", "style", "track", "video", "webidentity", "worker", 또는 "xslt".

요청은 연관된 대상(destination)을 가집니다. (destination type) 별도의 언급이 없으면 빈 문자열입니다.

이 값들은 RequestDestination 에 반영됩니다. 단, "serviceworker"와 "webidentity"는 해당 destination으로의 fetch가 서비스 워커를 건너뜁니다.

요청destination스크립트류(script-like)이면, 값이 "audioworklet", "paintworklet", "script", "serviceworker", "sharedworker", "worker" 중 하나입니다.

알고리즘에서 스크립트류를 사용할 때는 "xslt"도 스크립트 실행을 유발할 수 있음을 고려해야 합니다. 다만 항상 관련되지 않으며 별도 동작이 필요할 수 있어 목록에 포함하지 않았습니다.

다음 표는 요청initiator, destination, CSP 지시어, 그리고 기능(feature) 간의 관계를 보여줍니다. 이 표는 모든 기능을 포괄하지 않습니다. 각 기능은 해당 표준에서 관련 값을 정의해야 합니다.

Initiator Destination CSP 지시어 기능(Features)
"" "report" CSP, NEL 보고서.
"document" HTML의 navigate 알고리즘(최상위만).
"frame" child-src HTML의 <frame>
"iframe" child-src HTML의 <iframe>
"" connect-src navigator.sendBeacon(), EventSource, HTML의 <a ping="">, <area ping="">, fetch(), fetchLater(), XMLHttpRequest, WebSocket, Cache API
"object" object-src HTML의 <object>
"embed" object-src HTML의 <embed>
"audio" media-src HTML의 <audio>
"font" font-src CSS의 @font-face
"image" img-src HTML의 <img src>, /favicon.ico 리소스, SVG의 <image>, CSS의 background-image, CSS의 cursor, CSS의 list-style-image
"audioworklet" script-src audioWorklet.addModule()
"paintworklet" script-src CSS.paintWorklet.addModule()
"script" script-src HTML의 <script>, importScripts()
"serviceworker" child-src, script-src, worker-src navigator.serviceWorker.register()
"sharedworker" child-src, script-src, worker-src SharedWorker
"webidentity" connect-src Federated Credential Management 요청
"worker" child-src, script-src, worker-src Worker
"json" connect-src import "..." with { type: "json" }
"style" style-src HTML의 <link rel=stylesheet>, CSS의 @import, import "..." with { type: "css" }
"track" media-src HTML의 <track>
"video" media-src HTML의 <video> 요소
"download" "" HTML의 download="", "다른 이름으로 링크 저장…" UI
"imageset" "image" img-src HTML의 <img srcset>, <picture>
"manifest" "manifest" manifest-src HTML의 <link rel=manifest>
"prefetch" "" default-src (특정 지시어 없음) HTML의 <link rel=prefetch>
"prerender" HTML의 <link rel=prerender>
"xslt" "xslt" script-src <?xml-stylesheet>

CSP의 form-action은 HTML의 navigate 또는 form 제출 알고리즘에 직접 연결되어야 합니다.

CSP는 또한 다양한 CSP 지시어에 대해 요청clientglobal object연관 Document조상 navigable을 확인해야 합니다.


요청은 연관된 우선순위(priority)를 가집니다. 값은 "high", "low", "auto" 중 하나이며, 별도의 언급이 없으면 "auto"입니다.

요청은 연관된 내부 우선순위(internal priority)(null 또는 구현 정의(implementation-defined) 객체) 값을 가집니다. 별도의 언급이 없으면 null입니다.

요청은 연관된 origin을 가집니다. 값은 "client" 또는 origin입니다. 별도의 언급이 없으면 "client"입니다.

"client"는 origin으로 fetch 중에 변경됩니다. 이를 통해 표준에서 요청origin을 직접 설정하지 않아도 됩니다.

요청은 연관된 최상위 navigation initiator origin(top-level navigation initiator origin)을 가집니다. 값은 origin 또는 null입니다. 별도의 언급이 없으면 null입니다.

요청은 연관된 policy container를 가집니다. 값은 "client" 또는 policy container이며, 별도의 언급이 없으면 "client"입니다.

"client"는 policy containerfetch 중에 변경됩니다. 이를 통해 표준에서 요청policy container를 직접 설정하지 않아도 됩니다.

요청은 연관된 referrer를 가집니다. 값은 "no-referrer", "client", 또는 URL입니다. 별도의 언급이 없으면 "client"입니다.

"client"는 URL 또는 "no-referrer"로 fetch 중에 변경됩니다. 이를 통해 표준에서 요청referrer를 직접 설정하지 않아도 됩니다.

요청은 연관된 referrer policy를 가집니다. 값은 referrer policy이며, 별도의 언급이 없으면 빈 문자열입니다. [REFERRER]

이 값은 해당 요청에 사용할 referrer policy를 덮어쓸 때 사용될 수 있습니다.

요청은 연관된 mode를 가집니다. 값은 "same-origin", "cors", "no-cors", "navigate", 또는 "websocket"입니다. 별도의 언급이 없으면 "no-cors"입니다.

"same-origin"
동일 출처 URL에 대한 요청임을 보장합니다. fetch는 동일 출처가 아니면 네트워크 오류(network error)를 반환합니다.
"cors"
response tainting이 "cors"로 설정된 요청에 사용되며, CORS 요청이 되어, fetch는 요청된 리소스가 CORS 프로토콜을 이해하지 못하거나 CORS 프로토콜에 일부러 참여하지 않는 경우 네트워크 오류를 반환합니다.
"no-cors"
CORS-안전 목록 메서드CORS-안전 목록 요청 헤더만 사용할 수 있도록 제한합니다. 성공 시 fetch는 opaque 필터링된 응답을 반환합니다.
"navigate"
문서 간 탐색(navigating)에만 사용되는 특수 모드입니다.
"websocket"
웹소켓 연결(WebSocket connection)을 설정할 때만 사용되는 특수 모드입니다.

기본 요청mode가 "no-cors"이기는 하지만, 표준에서는 새로운 기능에 이 모드 사용을 적극 권장하지 않습니다. 이 모드는 안전하지 않습니다.

요청은 연관된 use-CORS-preflight 플래그를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

use-CORS-preflight 플래그가 설정된 것은 CORS-프리플라이트 요청이 발생하는 여러 조건 중 하나이다. use-CORS-preflight 플래그XMLHttpRequestUpload 객체에 하나 이상의 이벤트 리스너가 등록되었거나, ReadableStream 객체가 요청에 사용된 경우 설정된다.

요청은 연관된 credentials mode 를 가진다. 값은 "omit", "same-origin", "include" 중 하나이며, 별도 언급이 없으면 "same-origin"이다.

"omit"
이 요청에 credentials를 포함하지 않으며, 응답에 포함된 credentials도 무시된다.
"same-origin"
동일 출처 URL에 대한 요청에는 credentials를 포함하고, 동일 출처 응답에 포함된 credentials도 사용한다.
"include"
이 요청에는 항상 credentials를 포함하고, 응답에 포함된 credentials도 항상 사용한다.

요청credentials modefetchcredentials의 흐름을 제어한다. 요청mode가 "navigate"이면 credentials mode는 "include"로 간주되며, fetch는 현재 다른 값을 고려하지 않는다. HTML이 이 부분을 변경하면 이 표준도 그에 맞게 변경되어야 한다.

요청은 연관된 use-URL-credentials 플래그 를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

이 플래그가 설정된 경우, 요청URLusernamepassword가 있고, 해당 인증 항목(authentication entry)이 존재한다면, URL의 credentials가 인증 항목의 credentials보다 우선된다. 최신 명세에서는 URL에 credentials를 넣는 것을 권장하지 않으므로 이 플래그를 잘 사용하지 않지만, 과거 호환성 때문에 설정하는 경우가 있다.

요청은 연관된 cache mode를 가진다. 값은 "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" 중 하나이며, 별도 언급이 없으면 "default"이다.

"default"
fetch는 네트워크로 가기 전에 HTTP 캐시를 검사한다. 캐시에 일치하는 fresh response가 있으면 이를 반환한다. stale-while-revalidate response가 있으면 반환 후 조건부 네트워크 fetch로 캐시를 갱신한다. stale response가 있으면 조건부 네트워크 fetch로 캐시를 갱신한다. 없으면 조건 없는 네트워크 fetch로 캐시를 갱신한다. [HTTP] [HTTP-CACHING] [STALE-WHILE-REVALIDATE]
"no-store"
fetch는 HTTP 캐시가 전혀 없는 것처럼 동작한다.
"reload"
fetch는 네트워크로 가기 전 HTTP 캐시가 없는 것처럼 동작한다. 즉, 일반 요청을 만들고, 응답으로 캐시를 갱신한다.
"no-cache"
HTTP 캐시에 응답이 있으면 조건부 요청을, 없으면 일반 요청을 만든다. 그런 뒤 응답으로 캐시를 갱신한다.
"force-cache"
HTTP 캐시에 해당 요청에 일치하는 응답이 있으면 무조건 사용한다(오래됐는지 신경쓰지 않음). 없으면 일반 요청을 만들고, 응답으로 캐시를 갱신한다.
"only-if-cached"
HTTP 캐시에 해당 요청에 일치하는 응답이 있으면 무조건 사용한다(오래됐는지 신경쓰지 않음). 없으면 네트워크 오류를 반환한다. (요청mode가 "same-origin"일 때만 사용 가능. 캐시된 리다이렉트는 redirect mode가 "follow"이고 리다이렉트가 mode를 위반하지 않으면 따라감.)

헤더 목록다음 중 하나를 포함하면: `If-Modified-Since`, `If-None-Match`, `If-Unmodified-Since`, `If-Match`, 또는 `If-Range`, fetchcache mode가 "default"라면 "no-store"로 설정한다.

요청은 연관된 redirect mode를 가진다. 값은 "follow", "error", "manual" 중 하나이며, 별도 언급이 없으면 "follow"이다.

"follow"
리소스를 패칭할 때 발생하는 모든 리다이렉트를 따른다.
"error"
요청이 리다이렉트에 부딪히면 네트워크 오류(network error)를 반환한다.
"manual"
요청이 리다이렉트에 부딪히면 서비스 워커가 오프라인으로 리다이렉트를 재생할 수 있도록 opaque-redirect 필터링된 응답을 가져온다. 이 응답은 네트워크 오류와 구별할 수 없다. (원자적 HTTP 리다이렉트 처리를 위반하지 않기 위해.)

요청은 연관된 integrity metadata (문자열)을 가진다. 별도 언급이 없으면 빈 문자열이다.

요청은 연관된 암호학적 nonce metadata(cryptographic nonce metadata) (문자열)을 가진다. 별도 언급이 없으면 빈 문자열이다.

요청은 연관된 파서 메타데이터(parser metadata) 를 가진다. 값은 빈 문자열, "parser-inserted", "not-parser-inserted" 중 하나이며, 별도 언급이 없으면 빈 문자열이다.

요청암호학적 nonce metadata파서 메타데이터는 일반적으로 해당 요청을 생성한 HTML 요소의 속성 및 플래그에서 채워진다. 이는 콘텐츠 보안 정책(Content Security Policy)의 여러 알고리즘에서 특정 맥락에서 요청 또는 응답을 차단할지 판단하는 데 사용된다. [CSP]

요청은 연관된 reload-navigation 플래그 를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

이 플래그는 HTML의 navigate 알고리즘에서만 사용된다. [HTML]

요청은 연관된 history-navigation 플래그 를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

이 플래그는 HTML의 navigate 알고리즘에서만 사용된다. [HTML]

요청은 연관된 불리언 user-activation 을 가진다. 별도 언급이 없으면 false다.

이 값은 HTML의 navigate 알고리즘에서만 사용된다. [HTML]

요청은 연관된 불리언 render-blocking 을 가진다. 별도 언급이 없으면 false다.

이 플래그는 HTML의 render-blocking 메커니즘에서만 사용된다. [HTML]


요청은 연관된 URL 목록(URL list)을 가진다. (리스트이며, 하나 이상의 URL을 포함) 별도 언급이 없으면 요청URL을 복사해 리스트로 만든다.

요청은 연관된 current URL을 가진다. 이는 URL 리스트의 마지막 항목을 가리킨다.

요청은 연관된 redirect count 를 가진다. 별도 언급이 없으면 0이다.

요청은 연관된 response tainting 을 가진다. 값은 "basic", "cors", "opaque" 중 하나이며, 별도 언급이 없으면 "basic"이다.

요청은 연관된 prevent no-cache cache-control header modification flag 를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

요청은 연관된 done flag 를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

요청은 연관된 timing allow failed flag를 가진다. 별도 언급이 없으면 설정되지 않은 상태다.

요청URL 목록, current URL, redirect count, response tainting, done flag, timing allow failed flagfetch 알고리즘에서 부가적인 부기용으로 사용된다.


서브리소스 요청(subresource request)요청destination이 "audio", "audioworklet", "font", "image", "json", "manifest", "paintworklet", "script", "style", "track", "video", "xslt", 또는 빈 문자열일 때를 말한다.

비-서브리소스 요청(non-subresource request)요청destination이 "document", "embed", "frame", "iframe", "object", "report", "serviceworker", "sharedworker", "worker" 중 하나일 때를 말한다.

탐색 요청(navigation request)요청destination이 "document", "embed", "frame", "iframe", "object" 중 하나인 경우를 말한다.

이 용어들의 사용은 handle fetch를 참고하라. [SW]


redirect-taintrequest request에 대해 계산하려면 다음 단계를 따른다. 반환값은 "same-origin", "same-site", "cross-site" 중 하나이다.

  1. Assert: requestorigin이 "client"가 아님을 확인한다.

  2. lastURL을 null로 둔다.

  3. taint를 "same-origin"으로 둔다.

  4. requestURL 목록url에 대해:

    1. lastURL이 null이면 lastURLurl로 설정하고 continue한다.

    2. urloriginlastURLoriginsame site가 아니고, requestoriginlastURLoriginsame site가 아니면, "cross-site"를 반환한다.

    3. urloriginlastURLoriginsame origin이 아니고, requestoriginlastURLoriginsame origin이 아니면, taint를 "same-site"로 설정한다.

    4. lastURLurl로 설정한다.

  5. taint를 반환한다.

요청 origin 직렬화(Serializing a request origin)request request가 주어졌을 때 다음을 실행한다:

  1. Assert: requestorigin이 "client"가 아님을 확인한다.

  2. requestredirect-taint가 "same-origin"이 아니면, "null"을 반환한다.

  3. requestoriginascii 직렬화하여 반환한다.

요청 origin 바이트 직렬화(Byte-serializing a request origin)request request가 주어졌을 때, 요청 origin 직렬화의 결과를 등가 인코딩(isomorphic encoded)하여 반환한다.


복제(clone)request request에 대해 실행하려면 다음을 따른다:

  1. newRequestrequest의 복사본(단, body는 제외)으로 둔다.

  2. requestbody가 null이 아니면, newRequestbodyclone requestbody 결과로 설정한다.

  3. newRequest를 반환한다.


range 헤더 추가(add a range header)request request에, 정수 first와 옵션 정수 last와 함께 하려면 다음을 따른다:

  1. Assert: last가 주어졌다면, firstlast 이하임을 확인한다.

  2. rangeValue를 `bytes=`로 둔다.

  3. 직렬화등가 인코딩firstrangeValue에 추가한다.

  4. 0x2D (-)를 rangeValue에 추가한다.

  5. last가 주어졌다면, 직렬화등가 인코딩하여 rangeValue에 추가한다.

  6. 헤더 append(`Range`, rangeValue)를 requestheader list에 추가한다.

range 헤더는 양끝 포함 바이트 범위를 나타낸다. 즉, first가 0이고 last가 500이면 501 바이트 범위다.

여러 응답을 하나의 논리 리소스로 결합하는 기능은 역사적으로 보안 버그의 원인이었다. 부분 응답을 다루는 기능을 설계할 때는 반드시 보안 리뷰를 받을 것.


보고용 응답 URL 직렬화(serialize a response URL for reporting)response response에 대해 다음을 실행한다:

  1. Assert: responseURL list비어있지 않음을 확인한다.

  2. urlresponseURL list[0]의 복사본으로 둔다.

    이는 responseURL이 아니다. 리다이렉트 대상 정보 노출을 피하기 위함(이와 유사한 CSP 보고에 대한 고려도 참고). [CSP]

  3. username 설정url과 빈 문자열로 실행한다.

  4. password 설정url과 빈 문자열로 실행한다.

  5. 직렬화(serialization)url에 대해(단, fragment 제외 옵션 포함) 반환한다.

Cross-Origin-Embedder-Policy가 credentials를 허용하는지 확인하려면, request request가 주어졌을 때 다음을 실행한다:

  1. Assert: requestorigin이 "client"가 아님을 확인한다.

  2. requestmode가 "no-cors"가 아니면 true를 반환한다.

  3. requestclient가 null이면 true를 반환한다.

  4. requestclientpolicy containerembedder policyvalue가 "credentialless"가 아니면 true를 반환한다.

  5. requestoriginrequestcurrent URLorigin동일 출처이고, requestredirect-taint가 "same-origin"이 아니면 true를 반환한다.

  6. false를 반환한다.

2.2.6. 응답

fetch의 결과는 응답(response)이다. 응답은 시간이 지남에 따라 변화한다. 즉, 모든 필드가 즉시 사용 가능한 것은 아니다.

응답은 연관된 type을 가진다. 값은 "basic", "cors", "default", "error", "opaque", "opaqueredirect" 중 하나다. 별도 언급이 없으면 "default"이다.

응답은 연관된 aborted 플래그를 가질 수 있으며, 기본적으로 설정되지 않음이다.

이 플래그는 요청이 개발자나 최종 사용자에 의해 명시적으로 중단되었음을 나타낸다.

응답은 연관된 URL을 가진다. 이는 URL 리스트의 마지막 항목을 가리키며, 응답URL 리스트비어있으면 null이다.

응답은 연관된 URL 리스트(URL list)(리스트, 0개 이상의 URL 포함)을 가진다. 별도 언급이 없으면 « »이다.

첫 번째와 마지막 URL을 제외하면, 응답URL 리스트는 스크립트에 직접 노출되지 않는다. 이는 원자적 HTTP 리다이렉트 처리를 위반할 수 있기 때문이다.

응답은 연관된 status를 가진다. 값은 상태(status)이다. 별도 언급이 없으면 200이다.

응답은 연관된 status message를 가진다. 별도 언급이 없으면 빈 바이트 시퀀스이다.

HTTP/2 연결의 응답은 항상 빈 바이트 시퀀스를 status message로 가진다. HTTP/2는 status message를 지원하지 않는다.

응답은 연관된 헤더 목록(header list)을 가진다. (header list) 별도 언급이 없으면 « »이다.

응답은 연관된 본문(body)(null 또는 body)을 가진다. 별도 언급이 없으면 null이다.

네트워크 응답의 sourcelength 개념은 항상 null이다.

응답은 연관된 캐시 상태(cache state) (빈 문자열, "local", "validated")를 가진다. 별도 언급이 없으면 빈 문자열이다.

이 값은 서비스 워커리소스 타이밍에서 사용하기 위한 것이다. [SW] [RESOURCE-TIMING]

응답은 연관된 CORS 노출 헤더 이름 목록(CORS-exposed header-name list) (0개 이상의 헤더(header) 이름(name)의 리스트). 별도 언급이 없으면 비어 있음.

응답은 일반적으로 extracting header values를 통해 `Access-Control-Expose-Headers` 헤더에서 이 목록을 얻는다. 이 목록은 CORS 필터링 응답에서 노출할 헤더를 결정할 때 사용된다.

응답은 연관된 range-requested 플래그를 가질 수 있으며, 기본적으로 설정되지 않음이다.

이 플래그는 이전 범위 요청(ranged request)에서 온 부분 응답이, 범위 요청을 하지 않은 API에 제공되는 것을 막기 위해 사용된다. 플래그의 사용에 관한 자세한 설명은 해당 공격 설명을 참고.

응답은 연관된 request-includes-credentials (불리언)을 가진다. 기본값은 true이다.

응답은 연관된 timing allow passed 플래그를 가진다. 기본적으로 설정되지 않음이다.

이 플래그는 fetch 호출자가 패치된 리소스의 민감한 타이밍 데이터를 허용하는지 여부를 판단할 수 있도록 한다. 리다이렉트 체인 내 이전 응답에서 플래그가 설정되어 있으면 리다이렉트 응답에도 설정되어야 하므로, 이는 요청의 timing allow failed flag를 통해 내부적으로도 추적된다.

응답은 연관된 body info (response body info)를 가진다. 별도 언급이 없으면 새로운 response body info이다.

응답은 연관된 service worker timing info (null 또는 service worker timing info)를 가진다. 기본값은 null이다.

응답은 연관된 redirect taint ("same-origin", "same-site", "cross-site")를 가진다. 기본값은 "same-origin"이다.


네트워크 오류(network error)응답으로, type이 "error", status가 0, status message가 빈 바이트 시퀀스, header list가 « », body가 null이며, body info가 새로운 response body info인 경우이다.

중단된 네트워크 오류(aborted network error)네트워크 오류이면서, aborted 플래그가 설정된 경우이다.

적절한 네트워크 오류(appropriate network error)fetch params fetchParams에 대해 생성하려면:

  1. Assert: fetchParams취소(canceled) 상태임을 확인한다.

  2. fetchParams중단(aborted) 상태면 중단된 네트워크 오류(aborted network error)를 반환하고, 아니면 네트워크 오류를 반환한다.


필터링 응답(filtered response)은 연관된 응답(response)에 대해 제한된 뷰를 제공하는 응답이다. 이 연관된 응답filtered response내부 응답(internal response) (응답, 네트워크 오류 또는 filtered response가 아님)에서 얻을 수 있다.

별도 언급이 없으면 filtered response의 연관된 개념(예: body)은 내부 응답의 해당 개념을 참조한다. (아래에서 각 filtered response의 구체적 정의에 예외가 명시된다.)

fetch 알고리즘은 processResponse 및 유사한 파라미터를 통해 filtered response를 호출자에게 노출하여, 정보 누출을 방지한다. 레거시 사유로 정보가 노출되어야 할 때(예: 이미지 디코더에 데이터 전달), 명세 알고리즘에서는 연관된 내부 응답을 사용할 수 있다.

새 명세에서는 opaque filtered responseopaque-redirect filtered response를 기반으로 하지 않아야 한다. 이는 레거시 구조이며, 현대 컴퓨터 아키텍처에서는 항상 충분히 보호할 수 없다.

basic 필터링 응답(basic filtered response)filtered response 중, type이 "basic"이고, header list내부 응답header list에서, 이름금지된 응답 헤더 이름헤더를 제외한 것이다.

CORS 필터링 응답(CORS filtered response)filtered response 중, type이 "cors"이고, header list내부 응답header list에서, 이름CORS-안전 목록 응답 헤더 이름이 아닌 헤더내부 응답CORS 노출 헤더 이름 목록과 함께 제외한 것이다.

opaque 필터링 응답(opaque filtered response)filtered response 중, type이 "opaque"이고, URL 리스트가 « », status가 0, status message가 빈 바이트 시퀀스, header list가 « », body가 null, body info가 새로운 response body info인 경우이다.

opaque-redirect 필터링 응답(opaque-redirect filtered response)filtered response 중, type이 "opaqueredirect"이고, status가 0, status message가 빈 바이트 시퀀스, header list가 « », body가 null, body info가 새로운 response body info인 경우이다.

opaque-redirect filtered response에서 URL 리스트를 노출해도 해가 없다. 리다이렉트가 전혀 수행되지 않기 때문이다.

즉, opaque filtered responseopaque-redirect filtered response네트워크 오류와 거의 구별되지 않는다. 새 API에서는 내부 명세 알고리즘에서 내부 응답을 사용하지 마라. 정보가 노출될 수 있다.

이는 response.ok와 같은 JavaScript API가 쓸모없는 값을 반환할 수 있음을 의미한다.

type 값은 응답(response)의 속성으로, type getter를 통해 스크립트에서 확인할 수 있습니다:

console.log(new Response().type); // "default"

console.log((await fetch("/")).type); // "basic"

console.log((await fetch("https://api.example/status")).type); // "cors"

console.log((await fetch("https://crossorigin.example/image", { mode: "no-cors" })).type); // "opaque"

console.log((await fetch("/surprise-me", { redirect: "manual" })).type); // "opaqueredirect"

(여기서 다양한 리소스가 실제로 존재하고, https://api.example/status는 적절한 CORS 헤더를 갖추고 있으며, /surprise-me리다이렉트 상태를 사용하는 것을 가정합니다.)


복제(clone)응답(response) response에 대해 실행하려면:

  1. responsefiltered response라면, 동일한 filtered response를 새로 만들되, 내부 응답response내부 응답복제한 것으로 한다.

  2. newResponseresponse의 복사본(단, body는 제외)으로 둔다.

  3. responsebody가 null이 아니면, newResponsebody복제 responsebody로 설정한다.

  4. newResponse를 반환한다.


신선한 응답(fresh response)이란, 응답(response)현재 age(current age)신선도 수명(freshness lifetime) 이내에 있는 경우를 말합니다.

stale-while-revalidate 응답(stale-while-revalidate response)이란, 응답(response)신선한 응답(fresh response)이 아니고, 현재 agestale-while-revalidate 수명 이내인 경우를 말합니다. [HTTP-CACHING] [STALE-WHILE-REVALIDATE]

오래된 응답(stale response)이란 응답(response)신선한 응답이나 stale-while-revalidate 응답이 아닌 경우입니다.


location URL응답(response) response와 null 또는 ASCII 문자열 requestFragment가 주어졌을 때 아래 단계를 따라 값을 반환합니다. 반환 값은 null, failure, 또는 URL입니다.

  1. responsestatus리다이렉트 상태(redirect status)가 아니면 null을 반환합니다.

  2. locationextracting header list values에 `Location`과 responseheader list를 넘겨 호출한 결과로 둡니다.

  3. locationheader value라면, location파싱(parsing)한 결과로, base는 responseURL로 설정합니다.

    responseResponse 생성자로 만들어진 경우 responseURL은 null이므로, location절대 URL+fragment 문자열이어야만 파싱이 성공합니다.

  4. locationURL이고 fragment가 null이면, locationfragmentrequestFragment로 설정합니다.

    이렇게 하면 모든(합성 포함) 응답이 HTTP에서 정의된 리다이렉트 처리 모델을 따르게 됩니다. [HTTP]

  5. location을 반환합니다.

location URL 알고리즘은 오직 이 표준 및 HTML의 수동 리다이렉트 처리 navigate 알고리즘에서만 사용됩니다. [HTML]

2.2.7. 기타

잠재적 destination(potential destination)은 "fetch"이거나 빈 문자열이 아닌 destination이다.

변환(translate)잠재적 destination potentialDestination에 대해 실행하려면 다음을 따른다:

  1. potentialDestination이 "fetch"라면 빈 문자열을 반환한다.

  2. Assert: potentialDestinationdestination임을 확인한다.

  3. potentialDestination을 반환한다.

2.3. 인증 엔트리(Authentication entries)

인증 엔트리(authentication entry)프록시 인증 엔트리(proxy-authentication entry)는 HTTP 인증 및 HTTP 프록시 인증에 사용되는 username, password, realm의 튜플이며, 하나 이상의 요청(requests)과 연관된다.

사용자 에이전트는 이 둘을 HTTP 쿠키 및 유사 추적 기능과 함께 모두 삭제할 수 있도록 해야 한다.

자세한 사항은 HTTP에서 정의한다. [HTTP] [HTTP-CACHING]

2.4. Fetch 그룹(Fetch groups)

environment settings object는 연관된 fetch 그룹(fetch group)을 가지며, fetch group을 보유한다.

fetch group은 fetch에 대한 정보를 보유한다.

fetch group은 연관된 정보를 가진다:

fetch 레코드(fetch records)
리스트(list)이며, fetch record를 포함한다.
지연 fetch 레코드(deferred fetch records)
리스트(list)이며, deferred fetch record를 포함한다.

fetch recordstruct이며, 다음 항목(items)을 가진다:

request
request.
controller
fetch controller 또는 null.

deferred fetch recordstruct이며, 나중에 fetch를 실행하는 데 필요한 상태를 저장하는데 사용된다(예: 문서가 언로드되거나 fully active가 아니게 될 때 등). 다음 항목(items)을 가진다:

request
request.
notify invoked
인자를 받지 않는 알고리즘.
invoke state (기본값 "pending")
"pending", "sent", "aborted" 중 하나.

fetch group fetchGroup종료된 경우:

  1. fetch record recordfetchGroupfetch records에 있다면, recordcontroller가 null이 아니고, recordrequestdone flag가 unset이고, keepalive가 false라면, terminate recordcontroller를 실행한다.

  2. Process deferred fetchesfetchGroup에 대해 실행한다.

2.5. 도메인 해석

(This is a tracking vector.) origin 해석(resolve an origin)을 하려면, 네트워크 파티션 키(network partition key) keyorigin origin이 주어진다:

  1. originhostIP 주소라면, « originhost »를 반환한다.

  2. originhostpublic suffix가 "localhost" 또는 "localhost."라면, « ::1, 127.0.0.1 »를 반환한다.

  3. origin을 하나 이상의 IP 주소집합(set)으로 변환하는 구현 정의(implementation-defined) 작업을 수행한다.

    또한 단순히 IP 주소만 얻는 것 외에, 다른 연결 정보도 얻는 작업이 구현 정의로 수행될 수 있다. 예를 들어, originschemeHTTP(S) scheme라면, 구현체는 HTTPS RR에 대한 DNS 질의를 할 수도 있다. [SVCB]

    이 작업이 성공하면, IP 주소의 집합(set)과 추가 구현 정의 정보를 반환한다.

  4. 실패(failure)를 반환한다.

origin 해석 결과는 캐시될 수 있다. 캐시할 경우, key를 캐시 키의 일부로 사용해야 한다.

이 작업은 일반적으로 DNS를 포함하므로, DNS 서버에서 key를 고려하지 않고 캐시가 발생할 수 있다. 구현체에 따라 로컬에서 key를 고려할 수 없는 경우도 있다. [RFC1035]

IP 주소의 반환 순서는 origin 해석 알고리즘 호출마다 다를 수 있다.

(캐시 키를 제외한) 세부 사항은 현행 표준이 정의하는 시스템과 직접적으로 관련이 없으므로 구체적으로 명시하지 않는다. 다른 문서에서 이 프리미티브에 의존하고자 한다면, 반드시 현행 표준 커뮤니티와 충분한 논의가 선행되어야 한다.

2.6. 연결

사용자 에이전트는 연관된 연결 풀(connection pool)을 가진다. 연결 풀은 0개 이상의 순서 있는 집합(ordered set)이며, 각각의 연결(connection)키(key) (네트워크 파티션 키), origin(origin), credentials(불리언)로 식별된다.

connection은 연관된 timing info (connection timing info)를 가진다.

connection timing info는 연결 획득 과정의 타이밍 정보를 보관하는 struct이다. 다음 항목(items)을 가진다:

도메인 조회 시작 시각(domain lookup start time) (기본값 0)
도메인 조회 종료 시각(domain lookup end time) (기본값 0)
연결 시작 시각(connection start time) (기본값 0)
연결 종료 시각(connection end time) (기본값 0)
보안 연결 시작 시각(secure connection start time) (기본값 0)
DOMHighResTimeStamp.
ALPN 협상 프로토콜(ALPN negotiated protocol) (기본값: 빈 바이트 시퀀스)
바이트 시퀀스.

connection timing info clamp/coarsen 알고리즘은 connection timing info timingInfo, DOMHighResTimeStamp defaultStartTime, 불리언 crossOriginIsolatedCapability가 주어졌을 때 다음을 실행한다:

  1. timingInfoconnection start timedefaultStartTime보다 작으면, 모든 시각 값을 defaultStartTime으로 하고 ALPN negotiated protocoltimingInfo의 값을 사용한 새로운 connection timing info를 반환한다.

  2. 아니라면 각 시각 값을 coarsen time 알고리즘으로 crossOriginIsolatedCapability를 넘겨 처리한 값을 사용하고, ALPN negotiated protocoltimingInfo의 값을 사용한 새로운 connection timing info를 반환한다.


새 연결 설정(new connection setting)은 "no", "yes", "yes-and-dedicated" 중 하나이다.

연결 획득(obtain a connection) 알고리즘은 네트워크 파티션 키 key, URL url, 불리언 credentials, 옵션 new connection setting new (기본값 "no"), 옵션 불리언 requireUnreliable (기본값 false)로 호출한다:

  1. new가 "no"면:

    1. connections를 연결 풀에서 keykey, originurlorigin, credentialscredentialsconnection 집합으로 한다.

    2. connections가 비어 있지 않고 requireUnreliable이 false면 그 중 하나를 반환한다.

    3. connections 중에서 불안정 전송(unreliable transport, 예: HTTP/3)을 지원하는 connection이 있으면 그것을 반환한다.

  2. proxiesurl에 대한 프록시를 구현 정의 방식으로 찾은 결과로 한다. 프록시가 없으면 proxies는 « "DIRECT" »가 된다.

    이 단계에서는 Web Proxy Auto-Discovery Protocol(WPAD)이나 proxy auto-config(PAC) 등 비표준 기술도 사용된다. "DIRECT" 값은 해당 url에 프록시를 사용하지 않음을 의미한다.

  3. timingInfo를 새로운 connection timing info로 둔다.

  4. proxiesproxy에 대해:

    1. timingInfodomain lookup start timeunsafe shared current time으로 설정한다.

    2. hosts를 « urloriginhost »로 한다.

    3. proxy가 "DIRECT"면, hostsresolve an origin 알고리즘에 keyurlorigin을 넘겨 얻은 결과로 설정한다.

    4. hosts가 failure면 continue한다.

    5. timingInfodomain lookup end timeunsafe shared current time으로 설정한다.

    6. connection을 아래 단계로 얻는다: create a connection 알고리즘에 key, urlorigin, credentials, proxy, 구현 정의 host (from hosts), timingInfo, requireUnreliable를 넘겨서, 여러 번 병렬로 실행하고 하나 이상이 성공할 때까지 기다린다. 구현 정의 방식으로 반환값 하나를 선택해 반환한다. 나머지 connection들은 닫을 수 있다.

      즉, 구현체는 IP 주소 여러 개를 pick & race 하거나, IPv6를 우선하거나, 타임아웃 시 재시도하는 등 다양한 전략을 쓸 수 있다.

    7. connection이 failure면 continue한다.

    8. new가 "yes-and-dedicated"가 아니면 appendconnection을 연결 풀에 추가한다.

    9. connection을 반환한다.

  5. failure를 반환한다.

이 부분은 의도적으로 다소 모호하게 작성되어 있는데, 연결 관리에는 구현자 재량에 맡기는 것이 더 적합한 많은 미묘한 점들이 있기 때문이다. 이렇게 설명하는 것은 <link rel=preconnect> 기능을 설명하고, 연결인증 정보(credentials)를 기준으로 구분된다는 점을 명확히 하기 위함이다. 후자는 예를 들어, TLS 세션 식별자가 연결인증 정보(credentials)가 false인 것과 연결인증 정보(credentials)가 true인 것 사이에 재사용되지 않는다는 점을 명확히 한다.


연결 생성(create a connection) 알고리즘은 네트워크 파티션 키 key, origin origin, 불리언 credentials, 문자열 proxy, host host, connection timing info timingInfo, 불리언 requireUnreliable이 주어졌을 때 다음을 실행한다:

  1. timingInfoconnection start timeunsafe shared current time으로 설정한다.

  2. connection을 새 connection으로 만들고, keykey, originorigin, credentialscredentials, timing infotimingInfo로 한다. record connection timing infoconnection에 대해 실행하고, connection을 이용해 host에 HTTP 연결을 수립한다(프록시, origin을 고려). 단, 아래 주의사항에 유의: [HTTP] [HTTP1] [TLS]

    • requireUnreliable가 true면 불안정 전송(예: HTTP/3) 가능한 연결만 수립한다. [HTTP3]

    • 불안정 전송 연결을 수립할 때 WebTransport에 필요한 옵션을 활성화한다. HTTP/3의 경우, 초기 SETTINGS 프레임에 SETTINGS_ENABLE_WEBTRANSPORT=1, H3_DATAGRAM=1을 포함한다. [WEBTRANSPORT-HTTP3] [HTTP3-DATAGRAM]

    • credentials가 false면 TLS 클라이언트 인증서를 보내지 않는다.

    • 연결 수립에 실패(예: UDP, TCP, TLS 오류)하면 failure를 반환한다.

  3. timingInfoALPN negotiated protocolconnection의 ALPN Protocol ID로 설정한다. 단, 아래 주의사항에 유의: [RFC7301]

    • 프록시를 사용할 경우, 터널 연결이 성립하면 해당 터널링 프로토콜의 ALPN Protocol ID로, 아니면 프록시까지의 첫 홉의 ALPN Protocol ID로 설정한다.

    • 실험적·비공식 프로토콜을 쓰면, 실제 사용된 ALPN Protocol ID를 사용해야 한다. ALPN이 협상에 사용되지 않았다면 다른 설명 문자열을 써도 된다.

      timingInfoALPN negotiated protocol은 네트워크 프로토콜을 식별하기 위한 정보이며, ALPN이 협상에 쓰이지 않아도 실제 사용 프로토콜의 ALPN ID를 써야 한다.

    ALPN Protocol ID 목록은 IANA에서 관리한다. ALPN Protocol IDs 참고.

  4. connection을 반환한다.


connection timing info 기록(record connection timing info) 알고리즘은 connection connection에 대해 timingInfoconnectiontiming info로 두고, 다음 사항을 관찰한다:

connection timing info clamp/coarsen 알고리즘은 재사용된 연결의 상세 정보 노출 방지 및 시간값 coarsen을 보장한다.

2.7. 네트워크 파티션 키(Network partition keys)

네트워크 파티션 키(network partition key)site와 null 또는 구현 정의 값을 요소로 하는 튜플이다.

네트워크 파티션 키 결정(determine the network partition key) 알고리즘은 environment environment가 주어졌을 때 다음을 따른다:

  1. topLevelOriginenvironmenttop-level origin으로 둔다.

  2. topLevelOrigin이 null이면, topLevelOriginenvironmenttop-level creation URLorigin으로 둔다.

  3. Assert: topLevelOriginorigin이다.

  4. topLevelSiteobtain a site 알고리즘을 topLevelOrigin에 대해 실행한 결과로 둔다.

  5. secondKey를 null 또는 구현 정의 값 중 하나로 둔다.

    secondKey는 의도적으로 다소 모호하게 정의되어 있다. 세부 내용은 아직 발전 중임. issue #1035 참고.

  6. (topLevelSite, secondKey)를 반환한다.

네트워크 파티션 키 결정(determine the network partition key) 알고리즘은 request request가 주어졌을 때 다음을 따른다:

  1. requestreserved client가 null이 아니면, 네트워크 파티션 키 결정 알고리즘을 requestreserved client에 대해 실행한 결과를 반환한다.

  2. requestclient가 null이 아니면, 네트워크 파티션 키 결정 알고리즘을 requestclient에 대해 실행한 결과를 반환한다.

  3. null을 반환한다.

2.8. HTTP 캐시 파티션(HTTP cache partitions)

HTTP 캐시 파티션 결정(determine the HTTP cache partition) 알고리즘은 request request가 주어졌을 때 다음을 따른다:

  1. key네트워크 파티션 키 결정 알고리즘을 request에 대해 실행한 결과로 둔다.

  2. key가 null이면 null을 반환한다.

  3. key와 연관된 고유한 HTTP 캐시를 반환한다. [HTTP-CACHING]

2.9. 포트 차단(Port blocking)

새로운 프로토콜은 ALPN을 사용해 TLS를 통해 프로토콜을 협상함으로써 포트 차단의 필요성을 피할 수 있다. 이 경우 HTTP 요청을 통해 프로토콜이 위조될 수 없다. [RFC7301]

request request에 대해 나쁜 포트(bad port)로 인해 차단되어야 하는지 여부를 결정하려면:

  1. urlrequestcurrent URL로 둔다.

  2. urlschemeHTTP(S) scheme이고, urlport나쁜 포트(bad port)라면 blocked를 반환한다.

  3. allowed를 반환한다.

포트(port)나쁜 포트(bad port)이면 아래 표의 첫 번째 열에 나열된 값 중 하나이다.

포트 일반 서비스
0 —​
1 tcpmux
7 echo
9 discard
11 systat
13 daytime
15 netstat
17 qotd
19 chargen
20 ftp-data
21 ftp
22 ssh
23 telnet
25 smtp
37 time
42 name
43 nicname
53 domain
69 tftp
77 —​
79 finger
87 —​
95 supdup
101 hostname
102 iso-tsap
103 gppitnp
104 acr-nema
109 pop2
110 pop3
111 sunrpc
113 auth
115 sftp
117 uucp-path
119 nntp
123 ntp
135 epmap
137 netbios-ns
139 netbios-ssn
143 imap
161 snmp
179 bgp
389 ldap
427 svrloc
465 submissions
512 exec
513 login
514 shell
515 printer
526 tempo
530 courier
531 chat
532 netnews
540 uucp
548 afp
554 rtsp
556 remotefs
563 nntps
587 submission
601 syslog-conn
636 ldaps
989 ftps-data
990 ftps
993 imaps
995 pop3s
1719 h323gatestat
1720 h323hostcall
1723 pptp
2049 nfs
3659 apple-sasl
4045 npp
4190 sieve
5060 sip
5061 sips
6000 x11
6566 sane-port
6665 ircu
6666 ircu
6667 ircu
6668 ircu
6669 ircu
6679 osaut
6697 ircs-u
10080 amanda

2.10. responserequest에 대해 MIME 타입으로 차단해야 하는가?

다음 단계를 실행한다:

  1. mimeTyperesponseheader list에서 MIME 타입 추출의 결과로 둔다.

  2. mimeType이 failure라면 allowed를 반환한다.

  3. destinationrequestdestination으로 둔다.

  4. destinationscript-like이고, 아래 중 하나라도 해당되면 blocked를 반환한다:

    • mimeTypeessence가 "audio/", "image/", "video/"로 시작하는 경우
    • mimeTypeessence가 "text/csv"인 경우
  5. allowed를 반환한다.

3. HTTP 확장

3.1. 쿠키(Cookies)

`Cookie` 요청 헤더와 `Set-Cookie` 응답 헤더는 대부분 자체 명세에서 정의된다. 여기서는 이를 편리하게 사용하기 위한 추가 인프라를 정의한다. [COOKIES].

요청 `Cookie` 헤더 추가(append a request `Cookie` header) 알고리즘은 request request가 주어졌을 때 다음을 따른다:

  1. 사용자 에이전트가 request에 대해 쿠키를 비활성화하도록 설정되어 있다면, 리턴한다.

  2. sameSitesame-site 모드 결정 알고리즘을 request에 대해 실행한 결과로 둔다.

  3. isSecurerequestcurrent URLscheme이 "https"이면 true, 아니면 false로 둔다.

  4. httpOnlyAllowed를 true로 둔다.

    이는 fetch에서 호출되었기 때문에 true다. (예: document.cookie getter에서는 다를 수 있음)

  5. cookiesretrieve cookies 알고리즘에 isSecure, requestcurrent URLhost, requestcurrent URLpath, httpOnlyAllowed, sameSite를 넘겨 호출한 결과로 둔다.

    쿠키 저장소는 정렬된 쿠키 목록을 반환한다

  6. cookies비어있으면 리턴한다.

  7. valueserialize cookies 알고리즘에 cookies를 넘겨 실행한 결과로 둔다.

  8. Append (`Cookie`, value)를 requestheader list에 추가한다.

응답 `Set-Cookie` 헤더 파싱 및 저장(parse and store response `Set-Cookie` headers) 알고리즘은 request requestresponse response가 주어졌을 때 다음을 따른다:

  1. 사용자 에이전트가 request에 대해 쿠키를 비활성화하도록 설정되어 있다면 리턴한다.

  2. allowNonHostOnlyCookieForPublicSuffix를 false로 둔다.

  3. isSecurerequestcurrent URLscheme이 "https"이면 true, 아니면 false로 둔다.

  4. httpOnlyAllowed를 true로 둔다.

    이는 fetch에서 호출되어 true임(document.cookie getter 등에서는 다름).

  5. sameSiteStrictOrLaxAllowedsame-site 모드 결정 알고리즘이 request에 대해 "strict-or-less"를 반환하면 true, 아니면 false로 둔다.

  6. responseheader listheader에 대해:

    1. headername이 `Set-Cookie`와 바이트 대소문자 무시(byte-case-insensitive)로 일치하지 않으면 continue한다.

    2. Parse and store a cookie 알고리즘에 headervalue, isSecure, requestcurrent URLhost, requestcurrent URLpath, httpOnlyAllowed, allowNonHostOnlyCookieForPublicSuffix, sameSiteStrictOrLaxAllowed를 넘겨 실행한다.

    3. Garbage collect cookies 알고리즘에 requestcurrent URLhost를 넘겨 실행한다.

    `Set-Cookie` 헤더는 병합될 수 없으므로 각각 독립적으로 처리된다. 이는 다른 어떤 헤더에도 허용되지 않는다.

same-site 모드 결정(determine the same-site mode) 알고리즘은 request request에 대해 다음을 따른다:

  1. Assert: requestmethod가 "GET" 또는 "POST"임을 확인한다.

  2. requesttop-level navigation initiator origin이 null이 아니고, requestURLoriginsame site가 아니면, "unset-or-less"를 반환한다.

  3. requestmethod가 "GET"이고, requestdestination이 "document"이면, "lax-or-less"를 반환한다.

  4. requestclienthas cross-site ancestor가 true라면, "unset-or-less"를 반환한다.

  5. requestredirect-taint가 "cross-site"라면, "unset-or-less"를 반환한다.

  6. "strict-or-less"를 반환한다.

직렬화된 쿠키 기본 경로URL url로부터 얻으려면:

  1. cloneURLurl의 복제본으로 한다.

  2. cloneURLpath쿠키 기본 경로로 설정한다. 이때 cloneURLpath를 사용한다.

  3. cloneURLURL 경로 직렬화를 반환한다.

3.2. `Origin` 헤더

`Origin` 요청 헤더fetch가 어디에서 시작되었는지를 나타낸다.

`Origin` 헤더는 경로(path)를 노출하지 않는 `Referer` [sic] 헤더의 변형이다. 이는 HTTP fetchrequestresponse tainting이 "cors"이거나, requestmethod가 `GET` 또는 `HEAD`가 아닌 경우에 사용된다. 호환성 문제로 인해 모든 fetch에 포함되지는 않는다.

가능한 요청 origin의 바이트 직렬화(byte-serializing a request origin) 알고리즘이 request에 대해 반환하는 모든 값이다.

이 정의는 The Web Origin Concept의 정의를 대체한다. [ORIGIN]


요청 `Origin` 헤더 추가(append a request `Origin` header) 알고리즘은 request request가 주어졌을 때 다음을 실행한다:

  1. Assert: requestorigin이 "client"가 아님을 확인한다.

  2. serializedOrigin요청 origin의 바이트 직렬화 알고리즘을 request에 대해 실행한 결과로 둔다.

  3. requestresponse tainting이 "cors"이거나, requestmode가 "websocket"이면, append (`Origin`, serializedOrigin)을 requestheader list에 추가한다.

  4. 그렇지 않고 requestmethod가 `GET` 또는 `HEAD`가 아니라면:

    1. requestmode가 "cors"가 아니면, requestreferrer policy에 따라 분기한다:

      "no-referrer"

      serializedOrigin을 `null`로 설정한다.

      "no-referrer-when-downgrade"
      "strict-origin"
      "strict-origin-when-cross-origin"

      requestorigintuple origin이고, 그 scheme이 "https"이며, requestcurrent URLscheme이 "https"가 아니면, serializedOrigin을 `null`로 설정한다.

      "same-origin"

      requestoriginrequestcurrent URLorigin동일 출처(same origin)가 아니면, serializedOrigin을 `null`로 설정한다.

      그 외
      아무것도 하지 않는다.
    2. append (`Origin`, serializedOrigin)을 requestheader list에 추가한다.

requestreferrer policy는 fetcher가 서버와 origin을 명시적으로 공유하도록 설정하지 않은 모든 fetch에 대해 고려된다(예: CORS 프로토콜 사용 등).

3.3. CORS 프로토콜

교차 출처 응답 공유를 허용하고 HTML의 form 요소로 가능한 것보다 더 다양한 fetch를 허용하기 위해 CORS 프로토콜이 존재한다. 이는 HTTP 위에 계층화되어 있으며, 응답이 다른 origin과 공유될 수 있음을 선언하는 것을 허용한다.

방화벽(인트라넷) 뒤의 응답에서 데이터가 유출되는 것을 막기 위해 opt-in 메커니즘이어야 한다. 또한 requestcredentials가 포함되어 있을 때는 민감한 데이터 유출을 방지하기 위해서도 opt-in이어야 한다.

이 절에서는 서버 개발자를 위한 CORS 프로토콜을 설명한다. 사용자 에이전트에 대한 요구 사항은 fetch 알고리즘에 포함되어 있으며, 새로운 HTTP 헤더 문법을 제외한다.

3.3.1. 일반

CORS 프로토콜은 응답이 교차 출처로 공유 가능한지 나타내는 일련의 헤더로 구성된다.

HTML의 form 요소로 가능한 것보다 더 복잡한 request의 경우, CORS-사전 요청(CORS-preflight request)을 수행하여, requestcurrent URLCORS 프로토콜을 지원하는지 확인한다.

3.3.2. HTTP 요청

CORS 요청이란 `Origin` 헤더를 포함하는 HTTP 요청을 말한다. 이 헤더는 CORS 프로토콜에 참여하는지 신뢰성 있게 판별할 수 있는 기준이 되지 않는다. 왜냐하면 `Origin` 헤더는 requestmethod가 `GET` 또는 `HEAD`가 아닌 모든 경우에도 포함되기 때문이다.

CORS-사전 요청(CORS-preflight request)이란 CORS 요청으로, CORS 프로토콜이 적용 가능한지 확인하는 역할을 한다. 이 때 method는 `OPTIONS`이고 다음 헤더가 포함된다:

`Access-Control-Request-Method`

이후에 동일 리소스에 대해 할 CORS 요청이 어떤 method를 사용할 수 있는지 나타낸다.

CORS-사전 요청에는 다음 헤더도 포함될 수 있다:

`Access-Control-Request-Headers`

이후에 동일 리소스에 대해 할 CORS 요청이 어떤 헤더를 사용할 수 있는지 나타낸다.

3.3.3. HTTP 응답

CORS 요청에 대한 HTTP 응답에는 다음 헤더를 포함할 수 있다:

`Access-Control-Allow-Origin`

응답이 공유될 수 있는지 나타내며, 요청의 `Origin` 헤더의 리터럴 (또는 `null`)이나 `*`를 응답에서 반환한다.

`Access-Control-Allow-Credentials`

requestcredentials mode가 "include"일 때 응답이 공유될 수 있는지 나타낸다.

CORS-사전 요청의 경우 requestcredentials mode는 항상 "same-origin"(즉, credentials 미포함)이지만, 이후의 CORS 요청에서는 그렇지 않을 수 있다. 따라서 CORS-사전 요청의 HTTP 응답에도 지원 여부를 표시해야 한다.

CORS-사전 요청에 대한 HTTP 응답에는 다음 헤더를 포함할 수 있다:

`Access-Control-Allow-Methods`

응답의 responseURLCORS 프로토콜 목적으로 지원하는 method를 나타낸다.

`Allow` 헤더는 CORS 프로토콜 목적과는 무관하다.

`Access-Control-Allow-Headers`

응답의 responseURLCORS 프로토콜 목적으로 지원하는 헤더를 나타낸다.

`Access-Control-Max-Age`

`Access-Control-Allow-Methods`와 `Access-Control-Allow-Headers` 헤더의 정보를 몇 초(기본값 5초) 동안 캐시할 수 있는지 나타낸다.

CORS 요청이면서 CORS-사전 요청이 아닌 경우, 다음 헤더도 포함할 수 있다:

`Access-Control-Expose-Headers`

응답의 일부로 노출될 수 있는 헤더를 그 이름들을 나열하여 표시한다.


서버 개발자가 공유 의도가 있는 CORS 요청에 대한 성공적인 HTTP 응답은, 위에 명시된 헤더를 요청에 맞는 으로 포함하기만 하면 어떤 status도 사용할 수 있다.

CORS-사전 요청에 대한 성공적인 HTTP 응답도 유사하나, ok status (예: 200 또는 204)로 제한된다.

그 외의 HTTP 응답은 성공적이지 않으며, 공유가 불가능하거나 CORS-사전 요청에 실패한다. 서버에서 수행한 작업이 타이밍 등 부채널로 누출될 수 있음에 유의해야 한다. 서버 개발자가 이를 명시적으로 나타내고 싶다면, 403 status와 관련 헤더의 생략을 함께 사용할 수 있다.

원한다면 "실패"도 공유할 수 있지만, 이는 성공적인 HTTP 응답으로 간주된다. 따라서