Skip to content

Zoom-in: HTTP

Karify98·
Cover Image for Zoom-in: HTTP

Gõ địa chỉ, nhấn Enter, trang web hiện ra. Bên trong đó là nhiều tầng xếp chồng — mỗi tầng giải quyết một vấn đề mà tầng trước để lại.

graph LR
    A(["👤 Bạn"]) -->|"nhấn Enter"| B(["🌐 Trang web"])
    style A fill:#1e293b,stroke:#475569,color:#cbd5e1
    style B fill:#1e293b,stroke:#475569,color:#cbd5e1

Phóng to dần vào black box đó.


Layer 1 — Hai vai trò

Có hai máy tính tham gia: một bên hỏi, một bên trả lời.

graph LR
    C["💻 Client\n(Browser)"] -->|"hỏi"| S["🖥️ Server\nkarify98.site"]
    S -->|"trả lời"| C
    style C fill:#1e3a5f,stroke:#3b82f6,color:#93c5fd
    style S fill:#1a3a2a,stroke:#22c55e,color:#86efac

Client không tự có dữ liệu — phải xin từ server. Browser, mobile app, hay một service khác đều có thể là client.

Vấn đề còn lại: máy tính không hiểu tên miền. Nó chỉ hiểu địa chỉ IP.

Layer 2 — DNS: dịch tên sang địa chỉ

Trước khi hỏi được server, client cần biết server ở đâu.

graph LR
    C["💻 Client"] -->|"karify98.site ở đâu?"| D["🗂️ DNS"]
    D -->|"18.235.x.x"| C
    C -->|"hỏi"| S["🖥️ Server\n18.235.x.x"]
    S -->|"trả lời"| C
    style C fill:#1e3a5f,stroke:#3b82f6,color:#93c5fd
    style D fill:#3b2a1a,stroke:#f59e0b,color:#fcd34d
    style S fill:#1a3a2a,stroke:#22c55e,color:#86efac

DNS như danh bạ điện thoại — tra tên, nhận số. Kết quả được cache lại, nên lần sau không phải hỏi lại.

Vấn đề còn lại: biết địa chỉ rồi, nhưng gửi thẳng dữ liệu thì không đảm bảo đến nơi. Internet có thể mất gói tin.

Layer 3 — TCP: mở kênh truyền đáng tin cậy

Trước khi gửi dữ liệu, hai bên cần xác nhận đang nói chuyện được với nhau.

sequenceDiagram
    participant C as Client
    participant S as Server

    Note over C,S: DNS đã có IP — giờ mở kênh
    C->>S: SYN
    S-->>C: SYN-ACK
    C->>S: ACK
    Note over C,S: Kênh truyền đáng tin cậy đã mở

Ba bước bắt tay này đảm bảo cả hai đầu đều sẵn sàng. Nếu một gói tin bị mất, TCP tự gửi lại.

Vấn đề còn lại: kênh mở rồi, nhưng dữ liệu truyền dưới dạng plain text. Bất kỳ ai ở giữa đều đọc được.

Layer 4 — TLS: mã hóa kênh truyền

Chỉ có ở HTTPS. Hai bên trao đổi certificate và thỏa thuận encryption key trước khi gửi dữ liệu thật.

sequenceDiagram
    participant C as Client
    participant S as Server

    C->>S: TCP connect ✓
    C->>S: ClientHello — mình hỗ trợ cipher nào
    S-->>C: ServerHello + Certificate
    C->>S: Xác nhận certificate hợp lệ
    Note over C,S: Encryption key được thỏa thuận
    Note over C,S: Từ đây mọi dữ liệu đều được mã hóa 🔒

TLS không thay đổi cách HTTP hoạt động — chỉ bọc thêm một lớp mã hóa bên ngoài.

Vấn đề còn lại: kênh an toàn rồi. Nhưng hai bên nói gì với nhau?

Layer 5 — HTTP: ngôn ngữ của cuộc hội thoại

HTTP là quy ước về format câu hỏi và câu trả lời. Mỗi request có bốn thành phần:

GET /posts/hello-world HTTP/1.1
Host: karify98.site
Accept: text/html
Authorization: Bearer eyJhbGci...
Method GET · POST · PUT · DELETE — client muốn làm gì
Path /posts/hello-world — tài nguyên cụ thể
Headers Metadata: ai gửi, muốn nhận dạng gì, token xác thực
Body Dữ liệu đính kèm — chỉ có ở POST/PUT

Server nhận request, xử lý, và trả về response với status code — một con số nói lên kết quả.


Full picture

5 layer. 1 hành trình. Mỗi thứ tồn tại vì một lý do.

sequenceDiagram
    participant C as Client
    participant D as DNS
    participant S as Server

    C->>D: karify98.site ở đâu?
    D-->>C: 18.235.x.x

    C->>S: TCP connect (SYN → SYN-ACK → ACK)
    C->>S: TLS handshake 🔒
    S-->>C: Kênh mã hóa sẵn sàng

    C->>S: GET /posts/hello-world HTTP/1.1
    Note over S: xác thực → logic → DB query
    S-->>C: HTTP/1.1 200 OK + body

Status codes — server nói gì với client

Code Server đang nói gì
200OK — xong, đây là dữ liệu
201Created — tạo mới thành công
301Moved Permanently — địa chỉ đổi vĩnh viễn, nhớ cache lại
302Found — tạm đi chỗ khác, lần sau vẫn hỏi lại đây
400Bad Request — request sai format, lỗi từ phía client
401Unauthorized — chưa xác thực, đăng nhập trước
403Forbidden — đã xác thực nhưng không có quyền
404Not Found — không tìm thấy, hoặc không muốn cho biết
500Internal Server Error — lỗi code phía server
503Service Unavailable — server quá tải hoặc dependency không sẵn sàng

Ba nhầm lẫn phổ biến

404 vs 403

404: không tìm thấy — hoặc server chủ ý ẩn đi để không lộ thông tin. 403: tìm thấy, nhưng từ chối. Nhiều API trả 404 thay 403 là pattern bảo mật có chủ đích.

301 vs 302

301 vĩnh viễn: browser và search engine cache lại, không hỏi lại. 302 tạm thời: mỗi lần vẫn hỏi server. Sai một redirect, ảnh hưởng SEO cả tháng.

500 vs 503

500 là lỗi code: exception không bắt, null pointer, sai logic. 503 là lỗi tải: server alive nhưng database timeout, upstream không phản hồi. Debug ở hai chỗ hoàn toàn khác nhau.

Takeaway

Mỗi tầng trong hành trình tồn tại vì một lý do cụ thể — không phải vì ai thích thêm phức tạp. DNS vì máy tính không hiểu tên miền. TCP vì internet không đảm bảo gói tin đến nơi. TLS vì plain text không an toàn. HTTP vì cần một ngôn ngữ chung.

Khi debug, câu hỏi đúng không phải "tại sao lỗi" mà là "lỗi ở tầng nào" — DNS, TCP, TLS, hay HTTP logic?


Bài viết được hỗ trợ bởi Amy 🌸 - AI Assistant. Nội dung đã được kiểm duyệt bởi tác giả.

Related Posts