thư viện HTTP là gì
Hiểu về Thư viện HTTP: "Người phục vụ" đưa ứng dụng ra thế giới Internet
Hiểu một cách đơn giản, thư viện HTTP là "người phục vụ" giúp ứng dụng của bạn giao tiếp với máy chủ (server) trên Internet.
Khi bạn gọi lệnh gửi dữ liệu trong code (ví dụ fetch() trong JavaScript, requests trong Python, hay axios), thư viện HTTP sẽ biến dòng lệnh đơn giản đó thành các gói tin (packets) đúng chuẩn mạng để gửi đi.
📦 Dễ hình dung: Nhờ bưu điện gửi thùng hàng
Hãy tưởng tượng quá trình này giống như bạn muốn gửi một món hàng cho bạn bè:
- Bạn (Code của bạn): Chỉ bảo "Hãy gửi món hàng này đến địa chỉ B".
- Thư viện HTTP (Người đóng gói): Soạn nội dung thư theo chuẩn quy định (viết rõ gửi bằng phương thức gì: GET, POST..., đính kèm thông tin gì: Headers, Body...).
- Hệ điều hành & Card mạng (Bưu điện): Chia nhỏ món hàng/bức thư đó thành nhiều gói tin nhỏ (packets), dán nhãn địa chỉ IP nguồn và IP đích lên từng gói, rồi phát sóng Wi-Fi hoặc truyền qua dây cáp mạng đến máy chủ.
⚙️ Điều gì thực sự xảy ra bên dưới dòng code?
Khi bạn chạy 1 dòng code gửi request, quá trình đóng gói và gửi gói tin diễn ra qua các tầng:
- Soạn nội dung (Tầng Ứng dụng - HTTP):
Thư viện HTTP tạo ra một chuỗi văn bản định dạng đúng chuẩn HTTP:
GET /users HTTP/1.1 Host: api.example.com User-Agent: MyCustomApp/1.0 - Chia nhỏ & Đánh số (Tầng Vận chuyển - TCP): Nếu dữ liệu lớn, hệ thống sẽ chia chuỗi trên thành nhiều mảnh nhỏ. Tầng này mở một "đường truyền" (TCP Handshake) an toàn kết nối tới máy chủ (qua cổng 80 hoặc 443).
- Gắn địa chỉ & Tạo gói tin (Tầng Mạng - IP):
Mỗi mảnh dữ liệu được đóng gói vào một IP Packet, chứa:
- Payload: Nội dung dữ liệu HTTP.
- Header: Địa chỉ IP máy nhà bạn (IP Nguồn) và IP máy chủ (IP Đích).
- Bắn tín hiệu đi (Tầng Vật lý): Card mạng chuyển các gói tin (chứa chuỗi nhị phân 0 và 1) thành sóng radio (Wi-Fi) hoặc xung điện (cáp mạng) để gửi tới Router và đi tiếp trên Internet.
🛠️ Tại sao phải dùng "Thư viện HTTP" mà không tự gửi?
Nếu không có thư viện HTTP, bạn sẽ phải tự làm rất nhiều việc phức tạp:
- Tự mở Socket kết nối mạng cấp thấp.
- Tự định dạng chuỗi văn bản đúng từng khoảng trắng và dấu xuống dòng theo quy chuẩn HTTP.
- Tự quản lý việc kết nối lại khi rớt mạng, giải mã mã hóa SSL/TLS (https://), mã hóa dữ liệu JSON...
Thư viện HTTP ẩn đi toàn bộ các chi tiết phức tạp về gói tin và mạng bên dưới, giúp bạn chỉ cần tập trung viết logic cho ứng dụng.
Giải mã cấu trúc chi tiết của một HTTP Request
Một HTTP Request thực chất là một chuỗi văn bản (text) tuân theo định dạng chuẩn, được thư viện HTTP đóng gói trước khi chuyển cho lớp TCP/IP chia nhỏ gửi đi trên mạng.
Dưới đây là ví dụ chi tiết về cấu trúc của một gói tin HTTP Request điển hình (khi bạn thực hiện gửi thông tin đăng nhập hoặc gửi form dữ liệu).
📄 Ví dụ thực tế một gói tin HTTP Request
POST /api/v1/login HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/json
Content-Length: 47
Authorization: Bearer abc123xyztoken
{
"username": "user123",
"password": "secretPassword"
}
🧱 Cấu trúc 4 phần chính của HTTP Request
Cấu trúc một gói tin HTTP luôn gồm 4 thành phần được sắp xếp theo thứ tự nghiêm ngặt từ trên xuống dưới:
┌─────────────────────────────────────────────────────────┐
│ 1. Request Line (Dòng yêu cầu) │
├─────────────────────────────────────────────────────────┤
│ 2. Request Headers (Các dòng tiêu đề bổ sung) │
├─────────────────────────────────────────────────────────┤
│ 3. Blank Line (Một dòng trống bắt buộc \r\n) │
├─────────────────────────────────────────────────────────┤
│ 4. Message Body (Thân nội dung - Tùy chọn) │
└─────────────────────────────────────────────────────────┘
1. Request Line (Dòng khởi đầu)
Luôn nằm ở dòng đầu tiên, chứa 3 thông tin quan trọng cách nhau bởi khoảng trắng:
- HTTP Method (Phương thức): Cho máy chủ biết hành động muốn làm.
GET: Lấy dữ liệu.POST: Gửi/tạo mới dữ liệu.PUT / PATCH: Cập nhật dữ liệu.DELETE: Xóa dữ liệu.
- Request Target (Path/URL): Đường dẫn tài nguyên trên server (ví dụ:
/api/v1/login). - HTTP Version: Phiên bản HTTP sử dụng (thường là
HTTP/1.1hoặcHTTP/2).
2. Request Headers (Các tiêu đề)
Là các cặp Tên-Header: Giá-trị giúp cung cấp thêm thông tin ngữ cảnh cho Máy chủ:
| Header | Ý nghĩa / Mục đích |
|---|---|
| Host | Tên miền của máy chủ nhận request (Bắt buộc trong HTTP/1.1). |
| User-Agent | Thông tin về trình duyệt, thư viện HTTP hoặc thiết bị đang gọi request. |
| Content-Type | Định dạng của dữ liệu gửi kèm ở phần Body (ví dụ: application/json, application/x-www-form-urlencoded, multipart/form-data). |
| Content-Length | Kích thước tính bằng byte của phần Body. |
| Authorization | Chuỗi xác thực (Token, API Key, Password) để chứng minh quyền truy cập. |
| Accept | Báo cho server biết client có thể đọc/nhận định dạng phản hồi nào (ví dụ: application/json). |
3. Blank Line (Dòng trống)
- Một dòng trắng hoàn toàn (chứa ký tự ngắt dòng CRLF hay
\r\n). - Vai trò: Phân tách hoàn toàn giữa phần Headers và phần Body. Máy chủ đọc đến dòng trống này sẽ biết phần khai báo cấu hình đã xong, phía dưới (nếu có) sẽ là dữ liệu thô.
4. Message Body (Thân gói tin)
Chứa dữ liệu thực tế muốn truyền đi (nếu có):
- Thường xuất hiện trong các method
POST,PUT,PATCH. - Có thể là chuỗi JSON, XML, Form Data, hoặc nội dung Binary (khi tải file/ảnh lên).
- Đối với method
GEThoặcDELETE, phần này thường để trống.
Sự nâng cấp qua từng phiên bản HTTP chủ yếu tập trung vào việc tối ưu tốc độ, giảm độ trễ (latency) và khắc phục các điểm nghẽn của hạ tầng mạng bên dưới [cite: 18].
Dưới đây là so sánh chi tiết và sự khác biệt cốt lõi giữa HTTP/1.1, HTTP/2 và HTTP/3 [cite: 18].
📊 Bảng so sánh nhanh
| Tiêu chí | HTTP/1.1 (1997) | HTTP/2 (2015) | HTTP/3 (2020+) |
|---|---|---|---|
| Giao thức vận chuyển | TCP [cite: 18] | TCP [cite: 18] | QUIC (dựa trên UDP) [cite: 18] |
| Định dạng dữ liệu | Text (Văn bản thô) [cite: 18] | Binary (Mã nhị phân) [cite: 18] | Binary (Mã nhị phân) [cite: 18] |
| Xử lý đồng thời (Concurrency) | 1 Request/Response trên 1 kết nối [cite: 18] | Multiplexing (Nhiều Request/Response trên 1 kết nối) [cite: 18] | Multiplexing trên từng Stream độc lập [cite: 18] |
| Hiện tượng Head-of-Line Blocking | Lớp HTTP & Lớp TCP [cite: 18] | Lớp TCP [cite: 18] | Khắc phục hoàn toàn [cite: 18] |
| Bắt tay kết nối (Handshake) | Tốn 2-3 RTT (TCP + TLS) [cite: 18] | Tốn 2-3 RTT (TCP + TLS) [cite: 18] | Tốn 0-1 RTT (QUIC tích hợp sẵn TLS 1.3) [cite: 18] |
| Chuyển đổi mạng (Wifi <-> 4G/5G) | Bị đứt kết nối (dựa vào IP) [cite: 18] | Bị đứt kết nối (dựa vào IP) [cite: 18] | Không bị ngắt (dựa vào Connection ID) [cite: 18] |
🚀 Chi tiết cải tiến qua từng phiên bản
1. HTTP/1.1 - Kỷ nguyên Text & Kết nối nối tiếp
HTTP/1.1 là tiêu chuẩn truyền thông trong suốt nhiều năm, nhưng bộc lộ nhiều hạn chế khi các trang web ngày càng phức tạp [cite: 18]:
- Truyền tải dạng Text: Gói tin ở dạng văn bản thô, dễ đọc đối với con người nhưng tốn dung lượng và tốn tài nguyên xử lý của máy tính [cite: 18].
- Vấn đề Head-of-Line (HoL) Blocking ở lớp HTTP: Mỗi kết nối TCP chỉ xử lý từng Request/Response một. Nếu Request đầu tiên bị chậm, tất cả các Request phía sau phải xếp hàng đợi [cite: 18].
- Giải pháp tạm thời: Trình duyệt buộc phải mở nhiều kết nối TCP song song (thường tối đa 6-8 kết nối tới một Domain) để tải nhiều tệp cùng lúc, gây quá tải cho Server [cite: 18].
2. HTTP/2 - Kỷ nguyên Nhị phân & Multiplexing
HTTP/2 ra đời nhằm giải quyết triệt để điểm nghẽn ở lớp HTTP mà không làm thay đổi các khái niệm cốt lõi (Header, Method, URL...) [cite: 18]:
- Binary Framing Layer: Dữ liệu không gửi dạng Text nữa mà được nén và chia thành các khung nhị phân (Frames) [cite: 18].
- Multiplexing (Đa luồng): Cho phép gửi và nhận nhiều Request/Response cùng một lúc trên duy nhất một kết nối TCP. Dữ liệu được cắt nhỏ thành từng Frame, gửi đan xen nhau và ghép lại ở đích [cite: 18].
- Header Compression (HPACK): Nén phần Header vốn bị lặp đi lặp lại giữa các request, giúp giảm đáng kể kích thước gói tin [cite: 18].
- Server Push: Server có thể chủ động "đẩy" các tài nguyên (CSS, JS, hình ảnh) về client trước khi client gửi yêu cầu [cite: 18].
⚠️ Hạn chế của HTTP/2: Mặc dù giải quyết được HoL Blocking ở lớp HTTP, HTTP/2 vẫn chạy trên nền TCP. Nếu 1 gói tin TCP bị rớt (loss packet) trên đường truyền, toàn bộ các luồng dữ liệu khác trên kết nối TCP đó đều phải dừng lại chờ gửi lại gói tin bị mất [cite: 18].
3. HTTP/3 - Kỷ nguyên QUIC & Đột phá mạng không dây
Để khắc phục điểm nghẽn TCP cố hữu, HTTP/3 đã loại bỏ hoàn toàn TCP và chuyển sang sử dụng giao thức QUIC (chạy trên nền UDP) [cite: 18].
- Khắc phục triệt để Head-of-Line Blocking: Trong QUIC, mỗi stream dữ liệu là hoàn toàn độc lập. Nếu 1 gói tin của Stream A bị rớt, các Stream B, C vẫn tiếp tục tải bình thường mà không bị ngắt quãng [cite: 18].
- Bắt tay nhanh hơn (0-RTT / 1-RTT Handshake): QUIC tích hợp sẵn mã hóa TLS 1.3 vào quá trình thiết lập kết nối. Client và Server có thể trao đổi dữ liệu ngay trong lượt gửi đầu tiên (thay vì mất 2-3 lượt "chào hỏi" RTT như TCP + TLS) [cite: 18].
- Connection Migration (Chuyển mạng mượt mà): HTTP/1.1 và HTTP/2 định danh kết nối bằng IP và Cổng. Khi bạn chuyển từ Wi-Fi sang 4G/5G, IP đổi làm kết nối bị đứt. HTTP/3 dùng Connection ID độc lập với IP, cho phép video/cuộc gọi tiếp tục phát mượt mà ngay cả khi bạn đổi mạng [cite: 18].
Hướng dẫn kiểm tra phiên bản HTTP của trang web trực tiếp trên trình duyệt
Bạn có thể kiểm tra phiên bản HTTP mà một trang web (hoặc các tệp tài nguyên trên trang đó) đang sử dụng ngay trong trình duyệt Google Chrome, Microsoft Edge hoặc Brave bằng tính năng DevTools tích hợp sẵn [cite: 18].
Dưới đây là các bước thực hiện chi tiết [cite: 18]:
🛠️ Các bước kiểm tra qua Chrome / Edge DevTools
- Mở trang web bạn muốn kiểm tra (ví dụ:
google.com,facebook.comhoặc trang web của bạn) [cite: 18]. - Mở DevTools:
- Nhấn phím tắt
F12(hoặcCtrl + Shift + Itrên Windows /Cmd + Option + Itrên Mac) [cite: 18]. - Hoặc nhấp chuột phải bất kỳ đâu trên trang chọn Inspect (Kiểm tra) [cite: 18].
- Nhấn phím tắt
- Chuyển sang tab Network (Mạng):
- Nếu chưa thấy dữ liệu, hãy nhấn
F5(hoặcCtrl + R/Cmd + R) để tải lại trang. Lúc này danh sách các request sẽ xuất hiện [cite: 18].
- Nếu chưa thấy dữ liệu, hãy nhấn
- Bật cột Protocol (Giao thức):
- Theo mặc định, cột giao thức HTTP có thể bị ẩn [cite: 18].
- Nhấp chuột phải vào bất kỳ tiêu đề cột nào (như
Name,Status,Type...) Đánh dấu tích chọn Protocol [cite: 18].
🧐 Cách đọc kết quả trong cột Protocol
Sau khi bật cột Protocol, bạn sẽ thấy các ký hiệu tương ứng với các phiên bản HTTP [cite: 18]:
| Ký hiệu hiển thị trong cột Protocol | Phiên bản HTTP tương ứng |
|---|---|
http/1.1 |
HTTP/1.1 (Phiên bản cũ) [cite: 18] |
h2 |
HTTP/2 (Phiên bản phổ biến hiện nay) [cite: 18] |
h3 |
HTTP/3 (Chạy trên giao thức QUIC) [cite: 18] |
💡 Mẹo: Bạn sẽ thấy trên cùng một trang web, một số tài nguyên (ảnh, tệp script) tải qua
h3, một số tải quah2hoặchttp/1.1. Điều này là bình thường vì tùy thuộc vào máy chủ lưu trữ tài nguyên đó hỗ trợ giao thức nào [cite: 18].
🔍 Cách xem chi tiết gói tin HTTP của riêng một Request
Nếu bạn nhấp chuột trực tiếp vào một dòng Request trong tab Network [cite: 18]:
- Chọn tab Headers ở bảng bên phải [cite: 18].
- Tìm đến phần General:
- Tại mục Request URL và phiên bản giao thức (hoặc dòng thông số tổng quan), trình duyệt sẽ liệt kê chính xác các thông tin dòng lệnh Request/Response bao gồm phiên bản HTTP [cite: 18].
Hướng dẫn sử dụng tính năng Network Throttling trong DevTools để giả lập mạng yếu
Tính năng Network Throttling trong DevTools cho phép bạn giả lập các điều kiện mạng yếu (3G, 2G) hoặc ngắt kết nối hoàn toàn (Offline) để kiểm tra cách ứng dụng xử lý khi mạng chập chờn.
Dưới đây là các cách thực hiện đơn giản nhất trên Chrome / Edge / Brave:
🛠️ Cách 1: Thao tác nhanh trong tab Network (Phổ biến nhất)
- Mở DevTools bằng phím
F12(hoặcCtrl + Shift + I/Cmd + Option + I). - Chuyển sang tab Network.
- Ở thanh công cụ phía trên tab Network, tìm menu thả xuống đang ghi là No throttling (Mặc định).
- Nhấp vào menu đó và chọn cấu hình mạng bạn muốn giả lập:
- Offline: Ngắt mạng hoàn toàn (dùng để test giao diện offline, PWA, hoặc thông báo lỗi ngắt kết nối).
- Fast 3G: Giả lập mạng 3G tốc độ cao (độ trễ ~560ms).
- Slow 3G: Giả lập mạng 3G yếu/chậm (độ trễ ~2000ms - dùng để kiểm tra các nút loading, skeleton UI).
⚠️ Lưu ý: Chế độ này chỉ có hiệu lực khi cửa sổ DevTools đang mở. Khi đóng DevTools, mạng sẽ trở lại bình thường.
⚙️ Cách 2: Tự tạo cấu hình mạng tùy chỉnh (Custom Throttling)
Nếu các mức 3G mặc định chưa đúng nhu cầu (ví dụ: muốn test mạng 4G chập chờn hoặc mạng Wi-Fi rất lag), bạn có thể tự tạo thông số riêng:
- Trong menu thả xuống No throttling, chọn Add... (hoặc vào Settings DevTools Throttling).
- Nhấn nút Add custom profile....
- Điền các thông số:
- Profile Name: Tên gợi nhớ (ví dụ:
Very Slow Network). - Download / Upload: Tốc độ tải xuống/tải lên (tính bằng Kbps).
- Latency: Độ trễ kết nối (tính bằng ms - độ trễ càng cao thì request phản hồi càng chậm).
- Profile Name: Tên gợi nhớ (ví dụ:
- Nhấn Add để lưu, sau đó quay lại tab Network và chọn profile vừa tạo.
📶 Cách 3: Giả lập ngắt kết nối trên thiết bị di động (Sensors Panel)
Khi muốn test giao diện mobile kết hợp với việc bật/tắt Wi-Fi/Data nhanh:
- Nhấn
Ctrl + Shift + P(Windows) hoặcCmd + Shift + P(Mac) trong DevTools để mở Command Menu. - Gõ
Sensorsvà chọn Show Sensors. - Tại bảng Sensors hiện ra bên dưới, tìm mục Network orientation hoặc sử dụng toggle kết hợp với Device Mode (
Ctrl + Shift + M) để mô phỏng chính xác trải nghiệm người dùng mobile khi mất sóng.
💡 Cần kiểm tra (test) những gì khi mạng yếu/mất kết nối?
- Trạng thái Loading: Các nút bấm có bị khóa (
disabled) để tránh người dùng nhấn lặp lại (double submit) khi request đang chạy không? - Xử lý Lỗi (Error Handling): Ứng dụng có hiển thị thông báo lỗi thân thiện (như "Không có kết nối Internet, vui lòng thử lại") hay bị trắng màn hình / treo app?
- Thời gian Timeout: Các request quá lâu có tự động hủy và báo lỗi không, hay chờ đợi vô hạn?
- Trải nghiệm UX (Skeleton / Spinners): Người dùng có biết là ứng dụng đang tải dữ liệu hay tưởng ứng dụng bị hỏng?
Hướng dẫn sử dụng Local Overrides và Network Request Blocking trong DevTools để test API
Trong Chrome/Edge DevTools, tính năng Local Overrides và Network Request Blocking cho phép bạn chủ động can thiệp vào các API request mà không cần phải can thiệp hay chờ lập trình viên backend sửa API [cite: 18].
Dưới đây là 2 cách phổ biến nhất để test các kịch bản lỗi (như HTTP 404, 500) hoặc thay đổi dữ liệu trả về từ API [cite: 18].
🛠️ Cách 1: Chặn Request hoàn toàn (Network Request Blocking)
Dùng khi bạn muốn giả lập tình huống kết nối tới API bị lỗi mạng, server sập hoàn toàn, hoặc tài nguyên (ảnh/script) không tải được [cite: 18].
- Mở tính năng Network Request Blocking: Mở DevTools (
F12) Nhấn tổ hợp phímCtrl + Shift + P(Windows) hoặcCmd + Shift + P(Mac) GõBlockingChọn Show Network request blocking [cite: 18]. - Thêm quy tắc chặn (Pattern): Ở bảng Network request blocking hiện ra phía dưới:
- Đánh dấu tích vào ô Enable network request blocking [cite: 18].
- Nhấn vào dấu
+(Add pattern) [cite: 18]. - Nhập URL đầy đủ của API hoặc dùng dấu
*để chặn theo cụm (Ví dụ:*/api/v1/user/*hoặc*analytics.js*) [cite: 18].
- Test kết quả: Tải lại trang (
F5) hoặc thực hiện thao tác gửi request. Request bị chặn sẽ hiển thị trạng thái(blocked:devtools)trong tab Network, giúp bạn kiểm tra xem giao diện có hiển thị thông báo lỗi đúng cách không [cite: 18].
✏️ Cách 2: Sửa dữ liệu hoặc Mã Lỗi của API (Local Overrides)
Dùng khi bạn muốn ép API trả về mã lỗi cụ thể (ví dụ: 500 Internal Server Error, 403 Forbidden) hoặc sửa nội dung JSON Body để test các trường hợp edge-case [cite: 18].
Bước 1: Bật tính năng Local Overrides
- Trong DevTools, chuyển sang tab Sources [cite: 18].
- Ở thanh bên trái, chọn tab nhỏ Overrides (nếu không thấy, nhấp vào dấu
>>để tìm) [cite: 18]. - Nhấn + Select folder for overrides Chọn một thư mục rỗng bất kỳ trên máy tính của bạn để lưu các tệp ghi đè [cite: 18].
- Trình duyệt sẽ hiện một thanh hỏi cấp quyền truy cập ở phía trên Chọn Allow (Cho phép) [cite: 18].
Bước 2: Sửa trực tiếp Response của API
- Tìm API trong tab Network: Chuyển sang tab Network, thực hiện thao tác để API chạy, sau đó nhấp chuột phải vào tên Request muốn chỉnh sửa [cite: 18].
- Chọn chế độ Override:
- Nếu muốn sửa nội dung Response (JSON/Text): Chọn Override content [cite: 18].
- Nếu muốn sửa Header / HTTP Status Code (404, 500): Chọn Override headers [cite: 18].
- Chỉnh sửa dữ liệu theo ý muốn:
- Sửa Content: DevTools sẽ đưa bạn sang tab Sources. Bạn chỉ cần sửa chuỗi JSON thành dữ liệu mong muốn rồi nhấn
Ctrl + S(hoặcCmd + S) để lưu [cite: 18]. - Sửa Status Code: Trong tab Headers, bạn có thể nhấp đúp vào ô Status code để đổi thành
500 Internal Server Error,401 Unauthorizedhoặc404 Not Found[cite: 18].
- Sửa Content: DevTools sẽ đưa bạn sang tab Sources. Bạn chỉ cần sửa chuỗi JSON thành dữ liệu mong muốn rồi nhấn
- Kiểm tra giao diện: Quay lại ứng dụng và thực hiện lại thao tác. Lúc này, trình duyệt sẽ nhận Response từ file cục bộ của bạn thay vì nhận từ server thật (Request sẽ có biểu tượng dấu chấm chấm màu tím bên cạnh trong tab Network) [cite: 18].
💡 Tóm tắt khi nào dùng cách nào?
| Tình huống test | Giải pháp khuyên dùng |
|---|---|
| Test khi API bị rớt mạng / ngắt kết nối hoàn toàn [cite: 18] | Network Request Blocking (Cách 1) [cite: 18] |
| Test khi Server trả về mã lỗi 500, 403, 404 [cite: 18] | Local Overrides - Override Headers (Cách 2) [cite: 18] |
| Test trường hợp Dữ liệu JSON trả về bị thiếu trường / quá dài [cite: 18] | Local Overrides - Override Content (Cách 2) [cite: 18] |
Hướng dẫn toàn diện về Mock Service Worker (MSW) cho Frontend
Mock Service Worker (MSW) là một thư viện mock API thế hệ mới dành cho Frontend.
Điểm đặc biệt của MSW là nó hoạt động ở tầng mạng (Network level) bằng cách sử dụng Service Worker (trên trình duyệt) để chặn (intercept) các request outbound thật. Nhờ đó, ứng dụng Frontend của bạn gửi request đi như bình thường nhưng MSW sẽ bắt lấy request đó và trả về dữ liệu giả mà không hề đụng chạm hay sửa đổi mã nguồn gọi API (như fetch, axios).
💡 Tại sao MSW vượt trội hơn các cách Mock khác?
| Đặc điểm | Mock thủ công / Override trong code | MSW (Mock Service Worker) |
|---|---|---|
| Vị trí can thiệp | Thay đổi trực tiếp code gọi API (axios.get = ...) |
Chặn ở tầng Service Worker (Network Layer) |
| Tính chân thực | Không thấy request xuất hiện trong tab Network | Thấy request gửi đi và phản hồi thật trong tab Network |
| Sử dụng lại (Reusability) | Phải viết mock riêng cho Browser và Unit Test | Dùng chung 1 file Mock Handlers cho cả Browser, Jest, Vitest, Storybook |
| Tác động đến Codebase | Dễ sót code mock khi build Production | Tách biệt hoàn toàn, sản phẩm Production không bị dính code mock |
🛠️ Hướng dẫn từng bước cài đặt và sử dụng MSW (v2)
Dưới đây là các bước thiết lập MSW cơ bản trong một dự án React / Vue / Vite sử dụng REST API.
Bước 1: Cài đặt MSW
Cài đặt thư viện MSW dưới dạng devDependencies:
npm install msw --save-dev
# hoặc
yarn add msw --dev
Bước 2: Khởi tạo Service Worker file
Chạy lệnh CLI của MSW để tạo file mockServiceWorker.js vào thư mục tĩnh (public) của dự án (ví dụ thư mục public của Vite/React):
npx msw init public/ --save
Bước 3: Định nghĩa các API Handler (Mocks)
Tạo một file mới src/mocks/handlers.js để định nghĩa các request mà bạn muốn chặn và trả về dữ liệu giả:
import { http, HttpResponse } from 'msw'
export const handlers = [
// 1. Mock API lấy thông tin user (GET)
http.get('/api/user', () => {
return HttpResponse.json({
id: 'usr_123',
name: 'Nguyen Van A',
email: 'vana@example.com',
})
}),
// 2. Mock API Đăng nhập giả lập lỗi 500 (POST)
http.post('/api/login', async ({ request }) => {
const body = await request.json()
if (body.username !== 'admin') {
return new HttpResponse(null, {
status: 401,
statusText: 'Unauthorized',
})
}
return HttpResponse.json({ token: 'fake-jwt-token-xyz' })
}),
]
Bước 4: Cấu hình MSW Worker cho Browser
Tạo file src/mocks/browser.js để khởi tạo worker từ các handlers đã định nghĩa:
import { setupWorker } from 'msw/browser'
import { handlers } from './handlers'
export const worker = setupWorker(...handlers)
Bước 5: Kích hoạt MSW trong môi trường Development
Tích hợp việc khởi động worker vào file entry point của ứng dụng (ví dụ src/main.jsx hoặc src/index.js). Chỉ khởi chạy MSW khi ở môi trường development:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
async function enableMocking() {
// Chỉ kích hoạt khi chạy local / dev
if (process.env.NODE_ENV !== 'development') {
return
}
const { worker } = await import('./mocks/browser')
// Khởi chạy Service Worker
return worker.start({
onUnhandledRequest: 'bypass', // Cho phép các request không mock đi qua bình thường
})
}
enableMocking().then(() => {
ReactDOM.createRoot(document.getElementById('root')).render(<App />)
})
🚀 Kết quả thu được
Khi bạn bật ứng dụng ở môi trường Local Dev:
- Console trình duyệt sẽ hiển thị dòng chữ:
[MSW] Mocking enabled. - Mọi lệnh
fetch('/api/user')hayaxios.post('/api/login')sẽ tự động trả về dữ liệu mock do bạn định nghĩa trong filehandlers.js. - Bạn có thể mở tab Network trong DevTools để thấy các request được trả về nhanh chóng với HTTP Status Code chuẩn (
200,401,500...).
All Rights Reserved