Bỏ qua điều hướng

HTTP là gì? Cách trình duyệt và máy chủ trao đổi dữ liệu

Cấu trúc một request và response, ý nghĩa của các nhóm mã trạng thái, và vì sao HTTP/2 rồi HTTP/3 ra đời để giảm độ trễ và tăng bảo mật cho web.

Tuan Tran Van
17 phút đọc
Mục lục (10 phần)
  1. HTTP là gì?
  2. Một request đi từ trình duyệt tới server như thế nào?
  3. Một HTTP request gồm những gì?
  4. Các HTTP method nói lên điều gì?
  5. Response và các nhóm mã trạng thái
  6. HTTP đã tiến hóa ra sao, từ 0.9 đến HTTP/2?
  7. HTTP/3 và QUIC thay đổi điều gì?
  8. HTTP trong thực tế: nền tảng của API và mặt trái bảo mật
  9. Nắm HTTP tới đâu là đủ?
  10. Tài liệu tham khảo

HTTP (Hypertext Transfer Protocol) là giao thức truyền tải siêu văn bản, nền tảng kỹ thuật của toàn bộ World Wide Web.

Về mặt phân lớp mạng, HTTP hoạt động ở tầng ứng dụng (application layer) trên nền tảng bộ giao thức TCP/IP. Nó thiết lập các tiêu chuẩn chung để trình duyệt (client) và máy chủ (server) trao đổi dữ liệu, từ các tệp văn bản thô cho đến các tệp đa phương tiện phức tạp, đảm bảo tính thống nhất trong môi trường mạng toàn cầu.

Bạn có thể hình dung giao thức này như hệ thống vận chuyển thông tin của Internet: nó đảm bảo dữ liệu được đóng gói và chuyển từ điểm này đến điểm khác một cách chính xác. Không có các quy chuẩn mà HTTP đề ra, trình duyệt sẽ không biết cách yêu cầu tài nguyên và máy chủ cũng không biết cách phản hồi sao cho hiệu quả — trải nghiệm duyệt web hiện đại sẽ sụp đổ.

Trong kiến trúc hệ thống, HTTP cung cấp một lớp trừu tượng hóa mạnh mẽ, giúp kỹ sư không phải bận tâm đến các chi tiết hạ tầng phức tạp bên dưới khi xây dựng ứng dụng. Hiểu rõ cơ chế hoạt động của HTTP vừa giúp lập trình viên tối ưu tốc độ tải trang, vừa là chìa khóa để xử lý các vấn đề bảo mật và hiệu năng ở quy mô lớn.

Dòng dữ liệu HTTP chạy giữa trình duyệt và máy chủ trên Internet — hình ảnh chủ đề của bài viết

HTTP là gì?

HTTP xác định một tập hợp các quy tắc nghiêm ngặt để tiêu chuẩn hóa việc truyền tải nội dung giữa các thiết bị trên mạng Internet. Đây là một lớp trừu tượng (abstraction layer) giúp các nút mạng (hosts) giao tiếp mà không cần quan tâm đến cấu trúc phần cứng bên dưới. Trong mô hình client-server, client là phía khởi tạo yêu cầu (thường là trình duyệt) và server là phía tiếp nhận, xử lý để trả về các tài nguyên như HTML, hình ảnh hoặc video.

Mô hình client-server: trình duyệt gửi request tới máy chủ qua cổng 80, HTTPS mã hóa qua cổng 443

Theo tiêu chuẩn kỹ thuật, HTTP mặc định sử dụng cổng TCP 80 để liên lạc. Khi cần bảo mật, phiên bản mã hóa HTTPS dùng cổng 443 nhằm bảo vệ dữ liệu trên đường truyền qua lớp TLS (Transport Layer Security). Một điểm đặc thù cần nhớ: HTTP nguyên bản không lưu giữ thông tin về các giao dịch trước đó, mỗi yêu cầu được máy chủ tiếp nhận như một thực thể hoàn toàn mới.

Đặc tính không trạng thái (stateless) này vừa là ưu điểm vừa là thách thức. Nó cho phép hệ thống mở rộng dễ dàng vì máy chủ không tốn tài nguyên duy trì bộ nhớ về trạng thái của từng client. Đổi lại, để nhận diện người dùng hoặc duy trì phiên làm việc, kỹ sư phải triển khai thêm các cơ chế bổ trợ như cookies hoặc tokens gắn kèm trong headers của mỗi request.

Không có HTTP, Internet sẽ trở về thời kỳ sơ khai, nơi bạn phải nhớ chính xác địa chỉ IP của từng máy chủ. Bạn sẽ phải dùng các giao thức cấp thấp như TCP/IP để truyền dữ liệu thủ công, đánh mất sự tiện lợi của hệ thống liên kết siêu văn bản (hyperlink) và địa chỉ URL duy nhất cho từng tài nguyên mà bạn đang dùng hàng ngày.

Một request đi từ trình duyệt tới server như thế nào?

Quy trình bắt đầu ngay khi người dùng nhập URL hoặc tương tác với một liên kết. Trước khi một thông điệp HTTP được gửi đi, trình duyệt phải thiết lập kết nối tin cậy với máy chủ thông qua quy trình "bắt tay ba bước" (TCP Three-way Handshake). Bước này gồm việc client gửi gói SYN (Synchronize), server phản hồi SYN-ACK (Acknowledge) và cuối cùng client gửi lại ACK để hoàn tất việc mở luồng dữ liệu.

Bắt tay ba bước TCP: client gửi SYN, server trả SYN-ACK, client gửi ACK trước khi truyền request

Sau khi kết nối TCP được thiết lập, trình duyệt đóng gói yêu cầu thành một thông điệp HTTP và truyền qua socket đã mở. Thông điệp này chứa phương thức (như GET), đường dẫn tài nguyên và các headers cần thiết. Máy chủ khi nhận được gói tin sẽ bóc tách lớp giao thức, thực hiện các logic nghiệp vụ phía backend và tạo ra một thông điệp phản hồi (response) tương ứng để gửi ngược lại cho client.

Khi dữ liệu thô (thường là mã HTML hoặc JSON) quay trở lại, trình duyệt bắt đầu quá trình render nội dung. Quá trình này không dừng lại ở khâu hiển thị: trình duyệt phân tích mã nguồn để tiếp tục thực hiện các request bổ sung cho CSS, JavaScript hoặc hình ảnh cần thiết để hoàn thiện giao diện. Sau khi trao đổi kết thúc, kết nối có thể được đóng lại hoặc giữ lại tùy theo cấu hình của phiên bản HTTP đang dùng.

Đây là ví dụ về một request thô đơn giản để lấy trang chủ của một website:

http
GET /index.html HTTP/1.1
Host: www.example.com
Connection: keep-alive

Một HTTP request gồm những gì?

Cấu trúc của một thông điệp HTTP request được phân định rõ ràng thành các thành phần: HTTP Method, URL, Version, Headers và Body. Trong đó, URL không chỉ là một chuỗi ký tự mà bao gồm các phần định danh quan trọng: Scheme (giao thức), Domain (tên miền), Path (đường dẫn tài nguyên), và Query parameters (tham số truy vấn). Những thông tin này giúp server xác định chính xác vị trí và yêu cầu cụ thể đối với tài nguyên.

Cấu trúc một HTTP request gồm Method, URL, Version, Headers và Body, kèm các thành phần của URL

Headers là phần metadata, cung cấp các chỉ dẫn bổ sung để server xử lý request đúng ngữ cảnh. Header User-Agent giúp server nhận diện loại trình duyệt để trả về phiên bản web phù hợp, trong khi header Host là bắt buộc từ phiên bản HTTP/1.1 để hỗ trợ virtual hosting (nhiều website trên cùng một IP). Các headers như Accept hay Authorization kiểm soát định dạng dữ liệu và quyền truy cập vào tài nguyên.

Phần Body của request là tùy chọn và thường chỉ xuất hiện trong các phương thức như POST hoặc PUT. Đây là nơi chứa dữ liệu thực tế mà client muốn gửi lên máy chủ, chẳng hạn thông tin đăng ký người dùng dưới dạng JSON hoặc một tệp hình ảnh dưới dạng nhị phân. Độ dài của phần này được chỉ định qua header Content-Length để máy chủ biết khi nào quá trình nhận dữ liệu kết thúc.

Còn đây là một HTTP request thực tế, đầy đủ với các header phổ biến:

http
POST /api/v1/users HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/json
Authorization: Bearer abc123def456
Cache-Control: no-cache
Content-Length: 48
 
{
  "username": "admin",
  "email": "dev@example.com"
}

Các HTTP method nói lên điều gì?

Các HTTP method (thường gọi là "động từ" HTTP) chỉ định hành động mà client muốn thực hiện trên một tài nguyên nhất định. Phương thức GET được dùng rộng rãi nhất để truy xuất dữ liệu từ máy chủ mà không làm thay đổi trạng thái của tài nguyên đó. Ngược lại, POST được dùng khi client muốn gửi dữ liệu mới để máy chủ xử lý, thường dẫn đến việc tạo mới một bản ghi hoặc khởi động một quy trình nghiệp vụ.

Một điểm gây nhầm lẫn phổ biến cho các kỹ sư trẻ là sự khác biệt giữa POST và PUT. Theo đúng tiêu chuẩn, PUT dùng để cập nhật hoặc thay thế hoàn toàn một tài nguyên tại một đường dẫn (URL) cụ thể và có tính idempotency (thực hiện nhiều lần cho cùng kết quả). POST thì gửi dữ liệu vào một tập hợp (collection) và để server quyết định ID hoặc vị trí của tài nguyên mới đó.

Ngoài các phương thức phổ biến, kỹ sư hệ thống thường dùng phương thức HEAD để kiểm tra tính sẵn sàng của tài nguyên. Phương thức này yêu cầu máy chủ chỉ trả về các headers mà không có phần Body, giúp tiết kiệm băng thông khi cần kiểm tra kích thước tệp hoặc trạng thái cache. Phương thức DELETE, đúng như tên gọi, yêu cầu máy chủ gỡ bỏ hoàn toàn một tài nguyên khỏi hệ thống.

Phương thứcChức năng kỹ thuật
HEADChỉ yêu cầu thông tin trạng thái và header của tài nguyên (không lấy body).
GETTruy xuất hoặc lấy thông tin tài nguyên từ máy chủ.
POSTGửi dữ liệu mới để tạo tài nguyên hoặc xử lý logic phía server.
PUTCập nhật hoặc thay thế hoàn toàn tài nguyên tại một vị trí cụ thể.
DELETEXóa bỏ tài nguyên được chỉ định trên máy chủ.

Response và các nhóm mã trạng thái

Sau khi nhận và xử lý yêu cầu, máy chủ trả về một thông điệp phản hồi (HTTP Response). Cấu trúc của response tương tự request, bao gồm dòng trạng thái (Status line), các Headers cung cấp metadata như Content-Type hay Server, và cuối cùng là Body chứa dữ liệu thực tế. Dòng trạng thái chứa mã phiên bản HTTP, mã trạng thái số (Status Code) và một cụm từ giải thích (Reason Phrase) như "OK" hoặc "Not Found".

Năm nhóm mã trạng thái HTTP: 1xx thông tin, 2xx thành công, 3xx chuyển hướng, 4xx lỗi client, 5xx lỗi server

Hệ thống mã trạng thái HTTP được phân thành 5 nhóm chính dựa trên chữ số đầu tiên:

  • 1xx (Informational): Các phản hồi tạm thời, thông báo yêu cầu đã được nhận và đang tiếp tục xử lý.
  • 2xx (Success): Cho biết yêu cầu đã được xử lý thành công (ví dụ: 200 OK, 201 Created).
  • 3xx (Redirection): Thông báo tài nguyên đã thay đổi vị trí và client cần thực hiện thêm hành động để hoàn tất.
  • 4xx (Client Error): Lỗi xuất phát từ phía client, chẳng hạn sai cú pháp (400 Bad Request) hoặc không tìm thấy trang (404 Not Found).
  • 5xx (Server Error): Máy chủ gặp sự cố khi cố gắng thực hiện một yêu cầu hợp lệ (ví dụ: 500 Internal Server Error).

Nắm vững các mã trạng thái là kỹ năng debug tối quan trọng. Một mã 404 thường chỉ ra lỗi gõ sai URL hoặc tài nguyên đã bị xóa, trong khi mã 500 báo hiệu lỗi logic trong mã nguồn backend hoặc sự cố hệ thống cơ sở dữ liệu. Mã 301 (Moved Permanently) lại cực kỳ quan trọng cho SEO, giúp các công cụ tìm kiếm biết trang web đã chuyển sang địa chỉ mới vĩnh viễn.

Response Headers còn chứa các thông tin quan trọng về bảo mật và hiệu suất như Set-Cookie để quản lý phiên làm việc, hoặc các chỉ dẫn về cache để trình duyệt biết nên lưu trữ dữ liệu trong bao lâu. Body của response thường là mã HTML để render trang web, nhưng trong các hệ thống API hiện đại, nó chủ yếu chứa dữ liệu JSON hoặc XML để ứng dụng frontend xử lý.

HTTP đã tiến hóa ra sao, từ 0.9 đến HTTP/2?

Lịch sử của HTTP bắt đầu với phiên bản 0.9 (1991), vốn cực kỳ đơn giản với duy nhất phương thức GET và chỉ trả về văn bản HTML. Ở thời điểm đó, khái niệm "Hypertext" (siêu văn bản) hoàn toàn chính xác. Đến phiên bản 1.0 (1996), thuật ngữ này dần trở thành một "misnomer" (tên gọi nhầm) khi giao thức bắt đầu hỗ trợ cả hình ảnh và video, khiến "Hypermedia" trở thành thuật ngữ chính xác hơn về mặt bản chất kỹ thuật.

Dòng thời gian tiến hóa của HTTP từ phiên bản 0.9 năm 1991 đến HTTP/2 năm 2015

HTTP/1.0 gặp trở ngại lớn về hiệu năng do cơ chế đóng kết nối TCP ngay sau mỗi cặp request-response. Với các trang web hiện đại chứa hàng chục tài nguyên, việc lặp lại quy trình "bắt tay ba bước" gây ra độ trễ cực lớn. HTTP/1.1 (1999) cải tiến bằng cách giới thiệu kết nối bền vững (Persistent Connections) và Chunked Transfer Encoding, cho phép server gửi dữ liệu động theo từng mảnh mà không cần biết trước tổng kích thước (Content-Length).

Dù có Pipelining (gửi liên tiếp nhiều request mà không chờ từng phản hồi), HTTP/1.1 vẫn bị tắc nghẽn bởi lỗi "Head-of-Line Blocking", nơi một yêu cầu chậm có thể làm nghẽn toàn bộ hàng đợi phía sau. Điều này dẫn đến sự ra đời của HTTP/2 (2015), dựa trên SPDY của Google. HTTP/2 chuyển từ định dạng văn bản sang giao thức nhị phân và hỗ trợ Multiplexing, cho phép nhiều yêu cầu và phản hồi được gửi đồng thời trên cùng một kết nối duy nhất thông qua các Stream ID riêng biệt.

HTTP/2 còn mang lại cơ chế nén header HPACK, sử dụng mã hóa Huffman và bảng header để loại bỏ dữ liệu dư thừa giữa các request liên tiếp. Một tính năng khác là Server Push, cho phép máy chủ chủ động gửi tài nguyên (như file CSS) trước cả khi trình duyệt yêu cầu. Cơ chế RST_STREAM frame trong HTTP/2 cho phép client hủy bỏ một luồng dữ liệu mà không cần ngắt toàn bộ kết nối TCP, tiết kiệm tài nguyên hệ thống đáng kể.

HTTP/3 và QUIC thay đổi điều gì?

HTTP/3 đánh dấu một thay đổi lớn về hạ tầng khi loại bỏ TCP để chuyển sang chạy trên nền UDP thông qua giao thức QUIC (Quick UDP Internet Connections). TCP tuy ổn định nhưng lại chậm chạp trong việc xử lý mất gói tin và thiết lập kết nối trên các mạng không dây hiện đại. QUIC được thiết kế để giải quyết vấn đề "Head-of-Line Blocking" ở mức độ truyền tải, đảm bảo một luồng dữ liệu bị lỗi không làm ảnh hưởng đến các luồng khác.

So sánh HTTP/2 trên TCP và HTTP/3 trên QUIC: một gói tin mất chỉ ảnh hưởng tới luồng của chính nó

Một trong những tính năng đắt giá nhất của HTTP/3 là Connection Identifier (ID kết nối). Ở các phiên bản cũ, khi bạn chuyển từ mạng Wi-Fi sang 5G trên điện thoại, địa chỉ IP thay đổi khiến kết nối TCP bị đứt và phải bắt tay lại từ đầu. Với QUIC, phiên làm việc được định danh bằng ID thay vì cặp địa chỉ IP/Port, cho phép người dùng di chuyển mạng mượt mà mà không làm gián đoạn các phiên download hoặc livestream đang diễn ra.

Về mặt bảo mật, HTTP/3 tích hợp sâu TLS 1.3 vào ngay trong nhân giao thức, biến việc mã hóa thành yêu cầu mặc định thay vì tùy chọn. Điều này vừa bảo vệ dữ liệu tốt hơn, vừa giảm bớt số lần bắt tay cần thiết để thiết lập kết nối bảo mật (0-RTT), giúp giảm đáng kể độ trễ ban đầu khi truy cập trang web. QUIC xử lý việc xác thực và mã hóa đồng thời, mang lại tốc độ vượt trội so với mô hình xếp chồng TCP + TLS truyền thống.

Việc triển khai HTTP/3 vẫn vướng ở hai chỗ: mức hỗ trợ của các thư viện phần mềm và cấu hình tường lửa. Nhiều hệ thống hạ tầng mạng hiện nay vẫn mặc định chặn hoặc giới hạn lưu lượng UDP vì lo ngại các cuộc tấn công DDoS. Dù vậy, với sự thúc đẩy từ Google, Facebook và các nhà cung cấp CDN hàng đầu, HTTP/3 đang dần trở thành tiêu chuẩn mới cho trải nghiệm web tốc độ cao.

HTTP trong thực tế: nền tảng của API và mặt trái bảo mật

HTTP là nền tảng cho các kiến trúc API hiện đại như REST, GraphQL và SOAP. REST API tận dụng triệt để các phương thức HTTP để thực hiện các thao tác CRUD (tạo, đọc, cập nhật, xóa) một cách không trạng thái. GraphQL đi xa hơn bằng cách cung cấp một schema dữ liệu linh hoạt thông qua một endpoint duy nhất, giúp tối ưu việc lấy dữ liệu chính xác, trong khi SOAP dùng HTTP như một phương tiện vận chuyển cho các thông điệp XML có cấu trúc chặt chẽ.

Phổ biến là vậy, nhưng bản chất không trạng thái của HTTP cũng là một "gót chân Achilles" thường xuyên bị khai thác trong các cuộc tấn công DDoS ở tầng ứng dụng (Layer 7). Kẻ tấn công có thể gửi hàng triệu request HTTP hợp lệ lên server trong một thời gian ngắn. Do server phải xử lý từng request này (truy xuất DB, render trang), tài nguyên hệ thống (CPU/RAM) sẽ nhanh chóng cạn kiệt, khiến người dùng thực sự không thể truy cập dịch vụ.

Hiểu rõ cơ chế của HTTP Headers cũng giúp kỹ sư xây dựng lớp phòng thủ hiệu quả hơn. Các header như Authorization hay các cơ chế mã hóa trong HTTPS đảm bảo dữ liệu nhạy cảm không bị nghe lén hoặc sửa đổi bởi các cuộc tấn công "Man-in-the-Middle". Hiểu sâu về cách HTTP vận hành chính là bước đầu tiên để một kỹ sư hệ thống thiết kế các giải pháp cân bằng tải (Load Balancing) và phòng chống tấn công cho các ứng dụng quy mô lớn.

Nắm HTTP tới đâu là đủ?

Với một kỹ sư hệ thống hay lập trình viên web, vòng đời Request-Response là nền tảng bắt buộc. Bạn cần hiểu cách các headers ảnh hưởng đến hành vi của cache (thông qua Cache-Control) và cơ chế xác thực người dùng, đồng thời đọc được thông điệp HTTP thô để debug các lỗi kết nối phức tạp bằng Chrome DevTools hay Postman. Điều tách một kỹ sư giỏi khỏi phần còn lại là khả năng phân biệt khi nào lỗi nằm ở mạng (TCP/QUIC) và khi nào lỗi nằm ở logic ứng dụng (HTTP Status Codes).

Hãy ưu tiên thực hành với các tình huống thực tế — cấu hình Multiplexing trên NGINX, xử lý các vấn đề về CORS (Cross-Origin Resource Sharing — chia sẻ tài nguyên giữa các tên miền khác nhau) — thay vì học thuộc lòng bảng mã trạng thái. Và hãy nhớ một điều khi tối ưu: trên Internet, hiệu năng ứng dụng thường bị giới hạn bởi độ trễ mạng nhiều hơn là bởi sức mạnh xử lý của CPU.

Tài liệu tham khảo

Chia sẻ bài viết

X / TwitterFacebookLinkedIn