Warstwy HTTP w przeglądarce: od fetch() do QUIC
- data
- kategoria
- Frontend
- także w
- Backend · Networking
- czytanie
- 1 min / 199 słów
W kodzie frontendowym HTTP często wygląda tak:
const response = await fetch("/api/users/42");
const user = await response.json();
Dwie linie ukrywają kilka różnych warstw:
Fetch API
|
v
browser security / cache / cookies
|
v
HTTP semantics
|
v
HTTP/1.1, HTTP/2 or HTTP/3
|
v
TCP or QUIC
|
v
TLS
Ta seria schodzi pod fetch(), ale pozostaje serią dla frontendu.
Nie będziemy implementować parsera HTTP ani konfigurować kernela serwera. Interesuje nas to, co bezpośrednio wpływa na aplikację w browserze:
- dlaczego
404nie odrzuca Promise zfetch(), - czym różni się
GETodPOSTpoza nazwą, - dlaczego retry
POSTmoże być niebezpieczny, - skąd biorą się request headers, których nie ustawiliśmy,
- dlaczego niektórych headers JavaScript nie może kontrolować,
- kiedy browser wysyła body, cookies i credentials,
- dlaczego HTTP/1.1 generował inne waterfall niż HTTP/2,
- co naprawdę daje multiplexing,
- dlaczego HTTP/3 zmienił transport, ale nie semantykę
GET /api/users, - co dzieje się pomiędzy
fetch()a pierwszym bajtem odpowiedzi.
Osią serii będzie jedno rozróżnienie:
browser API
!=
HTTP semantics
!=
HTTP wire protocol
!=
transport
fetch() jest browser API.
GET, POST, status codes i headers należą do semantyki HTTP.
HTTP/1.1, HTTP/2 i HTTP/3 kodują oraz przenoszą tę semantykę w różny sposób.
TCP i QUIC są jeszcze niżej.
Dlatego ten sam kod:
fetch("/api/users")
może zostać wykonany przez HTTP/1.1, HTTP/2 albo HTTP/3 bez zmiany aplikacji.
Przejdziemy przez:
request / response
|
v
methods + status codes
|
v
headers + body
|
v
browser-controlled HTTP
|
v
connections
|
v
HTTP/1.1
|
v
HTTP/2
|
v
HTTP/3 + QUIC
|
v
full fetch lifecycle
Na końcu Network panel w DevTools powinien przestać wyglądać jak lista requestów.
Powinien wyglądać jak zapis decyzji browsera, protokołu i sieci.