Bạn đang duyệt trang web tin tức yêu thích của mình lần thứ ba trong ngày. Bạn nhấp làm mới, và trang tải gần như ngay lập tức. Trong hậu trường, trình duyệt của bạn thực sự không tải lại logo của trang web, tệp CSS stylesheet, hay các tệp JavaScript. Nó đã có sẵn chúng. Nó chỉ kiểm tra với máy chủ xem chúng có thay đổi không, và máy chủ đã đưa ra một phản hồi đơn giản, chỉ một dòng: 304 Not Modified.
Mã trạng thái nhỏ bé, hiệu quả này là một trong những anh hùng thầm lặng của hiệu suất web. Nó là lý do khiến web hiện đại cảm thấy nhanh chóng và phản hồi tốt. Nó là nền tảng của việc lưu trữ bộ nhớ đệm (caching), và nó tiết kiệm hàng tỷ gigabyte băng thông mỗi ngày. Thoạt nhìn, nó có thể không thú vị bằng một chuyển hướng hay một mã lỗi, nhưng tin tôi đi, nó là một trong những công cụ mạnh mẽ nhất để làm cho các trang web và API nhanh hơn và hiệu quả hơn.
Mã 304 không phải là lỗi; đó là một xác nhận thành công, hiệu quả. Đó là cách máy chủ nói, "Bạn đã có phiên bản mới nhất của tệp này được lưu cục bộ. Tôi không cần phải gửi lại nó. Cứ sử dụng những gì bạn có."
Trong bài đăng blog này, chúng ta sẽ đi sâu vào ý nghĩa của 304 Not Modified, cách nó hoạt động, tại sao nó quan trọng và cách các nhà phát triển có thể sử dụng nó để xây dựng các trang web và API nhanh hơn, phản hồi tốt hơn. Nếu bạn là nhà phát triển, việc hiểu cách 304 hoạt động là rất quan trọng để xây dựng các ứng dụng nhanh, hiệu quả và có khả năng mở rộng.
Trước khi chúng ta bắt đầu, nếu bạn muốn kiểm tra và khám phá cách các máy chủ web hoặc API của bạn xử lý các phản hồi như 304 Not Modified, hãy đảm bảo tải xuống Apidog miễn phí. Apidog là một công cụ kiểm thử và tài liệu API mạnh mẽ giúp bạn khám phá các phản hồi HTTP, xác thực phản hồi và tối ưu hóa backend của bạn như một chuyên gia. Tuyệt vời nhất là, nó miễn phí để tải xuống. Hãy bắt đầu tối ưu hóa API của bạn ngay hôm nay.
button
Bây giờ, hãy cùng đi sâu vào mã trạng thái HTTP 304 Not Modified và xem tại sao nó lại quan trọng đến vậy.
Vấn đề: Truyền dữ liệu lãng phí
Trong những ngày đầu của web, mọi yêu cầu đều hoạt động theo cùng một cách:
- Trình duyệt: "Hãy cho tôi
/logo.png." - Máy chủ: "Đây rồi!" (`200 OK` + dữ liệu hình ảnh đầy đủ)
- Trình duyệt (2 giây sau): "Hãy cho tôi
/logo.pngmột lần nữa." - Máy chủ: "Đây rồi một lần nữa!" (`200 OK` + cùng một dữ liệu hình ảnh)
Điều này cực kỳ lãng phí. Cùng một logo, stylesheet và các script đã được truyền qua mạng hàng chục lần mỗi ngày cho một người dùng, tiêu tốn băng thông và làm chậm quá trình tải trang.
Giải pháp cho sự kém hiệu quả này là một quy trình hai phần: lưu trữ bộ nhớ đệm (caching) và **các yêu cầu có điều kiện (conditional requests)**, với mã trạng thái `304` là ngôi sao của chương trình.
HTTP 304 Not Modified thực sự có nghĩa là gì?
Mã trạng thái **304 Not Modified** là một phản hồi giống như chuyển hướng, cho biết rằng máy chủ không cần phải truyền tài nguyên được yêu cầu vì máy khách đã có một phiên bản cập nhật trong bộ nhớ đệm cục bộ của nó.
Đó là một thông báo thành công với phần thân trống. Máy chủ về cơ bản đang nói, "Yêu cầu của bạn đã thành công. Tài nguyên bạn yêu cầu không thay đổi. Tôi không có gì mới để gửi cho bạn."
Nói cách khác, thay vì lãng phí băng thông bằng cách gửi đi gửi lại cùng một dữ liệu, máy chủ chỉ đơn giản phản hồi bằng một **xác nhận nhẹ nhàng**.
Một phản hồi `304` điển hình cực kỳ tối giản:
HTTP/1.1 304 Not ModifiedCache-Control: public, max-age=300ETag: "a3c8d7e1f5g2"Date: Sat, 28 Oct 2023 10:00:00 GMT
Bạn có nhận thấy điều gì thiếu không? **Phần thân phản hồi**. Không có dữ liệu hình ảnh, không có CSS, không có JSON. Đây là điều làm cho `304` trở nên hiệu quả. Toàn bộ phản hồi chỉ là vài trăm byte tiêu đề, tiết kiệm hàng megabyte dữ liệu mà lẽ ra đã nằm trong phần thân.
Tại sao 304 tồn tại? (Lịch sử ngắn gọn)
Trở lại những ngày đầu của web, mỗi khi bạn tải một trang web, trình duyệt sẽ lấy mọi thứ HTML, CSS, hình ảnh, script từ đầu. Điều này chậm và lãng phí.
Để giải quyết vấn đề này, **HTTP đã giới thiệu các cơ chế lưu trữ bộ nhớ đệm** như `Last-Modified` và `ETag`. Mã trạng thái **304** được thiết kế để:
- Tiết kiệm băng thông.
- Giảm tải máy chủ.
- Tăng tốc thời gian phản hồi.
Nó trở thành một tiêu chuẩn trong **HTTP/1.1** và vẫn là một nền tảng của hiệu suất web ngày nay.
Tại sao 304 Not Modified quan trọng
Hãy nghĩ theo cách này: Mỗi khi người dùng truy cập một trang web hoặc yêu cầu một tài nguyên API, việc tải xuống toàn bộ nội dung mỗi lần có thể chậm và lãng phí, đặc biệt đối với người dùng di động hoặc trên các kết nối chậm. Bằng cách tận dụng 304 Not Modified:
- Nó giảm truyền dữ liệu không cần thiết, do đó người dùng tải trang nhanh hơn và nhà cung cấp tiết kiệm băng thông.
- Nó giảm tải máy chủ vì máy chủ không phải gửi lại các phản hồi đầy đủ nhiều lần.
- Nó cải thiện trải nghiệm người dùng với thời gian tải nhanh hơn và điều hướng mượt mà hơn.
- Nó hỗ trợ khả năng mở rộng bằng cách xử lý hiệu quả các yêu cầu lặp lại.
Nếu không có 304, bộ nhớ đệm sẽ không hiệu quả và các trang web sẽ chậm hơn.
Vũ điệu hai bước: Cách Caching và 304 hoạt động cùng nhau
Mã `304` không hoạt động một mình. Nó là một phần của một vũ điệu tinh tế giữa máy khách và máy chủ.
Bước 1: Yêu cầu đầu tiên (Yêu cầu "Gieo hạt")
Lần đầu tiên trình duyệt yêu cầu một tài nguyên, máy chủ phản hồi với hai thông tin quan trọng cùng với dữ liệu (200 OK):
ETag (Thẻ thực thể): Một định danh duy nhất, giống như dấu vân tay, cho phiên bản hiện tại của tài nguyên. Đây thường là một mã băm (hash) của nội dung tệp. Nếu tệp thay đổi, ETag cũng thay đổi.
ETag: "a3c8d7e1f5g2"
Last-Modified (Lần sửa đổi cuối cùng): Ngày và giờ tài nguyên được thay đổi lần cuối.
Last-Modified: Sat, 28 Oct 2023 09:00:00 GMT
Trình duyệt lưu trữ tài nguyên và hai trình xác thực này trong bộ nhớ đệm của nó.
Bước 2: Yêu cầu tiếp theo (Yêu cầu "Có điều kiện")
Khi trình duyệt cần cùng một tài nguyên một lần nữa (ví dụ: người dùng truy cập một trang khác trên cùng một trang web), nó không chỉ yêu cầu một cách mù quáng. Nó thực hiện một **yêu cầu có điều kiện** bằng cách bao gồm các trình xác thực mà nó đã lưu.
Nó có thể làm điều này theo hai cách:
Sử dụng tiêu đề `If-None-Match` (với ETag):
GET /logo.png HTTP/1.1Host: www.example.comIf-None-Match: "a3c8d7e1f5g2"
Yêu cầu này nói: "Vui lòng gửi cho tôi `/logo.png` **chỉ khi** ETag hiện tại của nó khác với ETag mà tôi đã có (a3c8d7e1f5g2)."
Sử dụng tiêu đề `If-Modified-Since` (với ngày):
GET /logo.png HTTP/1.1Host: www.example.comIf-Modified-Since: Sat, 28 Oct 2023 09:00:00 GMT
Yêu cầu này nói: "Vui lòng gửi cho tôi `/logo.png` **chỉ khi** nó đã được sửa đổi kể từ ngày 28 tháng 10."
Bước 3: Quyết định của máy chủ
Máy chủ nhận yêu cầu có điều kiện này và kiểm tra tài nguyên.
- TRƯỜNG HỢP A: Tài nguyên KHÔNG THAY ĐỔI. Máy chủ thấy rằng ETag hiện tại vẫn khớp với
"a3c8d7e1f5g2". Nó phản hồi với `304 Not Modified` và không gửi dữ liệu tài nguyên. - TRƯỜNG HỢP B: Tài nguyên ĐÃ THAY ĐỔI. Máy chủ thấy ETag không còn khớp. Nó phản hồi với `200 OK`, dữ liệu tài nguyên đầy đủ và **các tiêu đề `ETag` và `Last-Modified` mới** để trình duyệt lưu vào bộ nhớ đệm.
Cơ chế bắt tay tinh tế này đảm bảo dữ liệu chỉ được truyền khi thực sự cần thiết.
Vai trò của tiêu đề HTTP trong phản hồi 304
Sự kỳ diệu của 304 nằm ở các tiêu đề. Hai yếu tố chính là:
- Last-Modified → cho khách hàng biết khi nào tài nguyên được cập nhật lần cuối.
- ETag (Entity Tag) → một định danh duy nhất cho phiên bản của tài nguyên.
Khi máy khách gửi `If-Modified-Since` hoặc `If-None-Match`, máy chủ kiểm tra:
- Nếu không thay đổi → trả về **304**.
- Nếu thay đổi → trả về **200 OK** với tài nguyên mới.
ETag và Last-Modified là gì?
- ETag (Thẻ thực thể): Một định danh duy nhất (thường là một mã băm) đại diện cho phiên bản của một tài nguyên.
- Last-Modified: Dấu thời gian cho biết khi nào tài nguyên được thay đổi lần cuối.
Máy khách gửi các giá trị này dưới dạng tiêu đề có điều kiện trong các yêu cầu lặp lại để kiểm tra xem nội dung có thay đổi không.
Các trường hợp sử dụng phổ biến cho phản hồi 304
- Các trang web có tài sản tĩnh (CSS, JS, hình ảnh).
- REST API trả về kết quả JSON lớn.
- Ứng dụng di động dựa vào đồng bộ hóa máy chủ.
- CDN tối ưu hóa phân phối nội dung.
- Tối ưu hóa việc **thu thập dữ liệu của công cụ tìm kiếm**.
Ví dụ về quy trình 304
Dưới đây là một ví dụ đơn giản giữa trình duyệt và máy chủ:
Yêu cầu ban đầu
textGET /styles.css HTTP/1.1 Host: example.com
Phản hồi ban đầu
`textHTTP/1.1 200 OK ETag: "abc123" Last-Modified: Tue, 15 Sep 2025 11:00:00 GMT Content-Type: text/css
/* CSS styles here */`Yêu cầu tiếp theo
textGET /styles.css HTTP/1.1 Host: example.com If-None-Match: "abc123" If-Modified-Since: Tue, 15 Sep 2025 11:00:00 GMT
Phản hồi của máy chủ (Không thay đổi)
textHTTP/1.1 304 Not Modified
Vì máy chủ nói rằng nội dung không thay đổi, trình duyệt sử dụng bản sao đã lưu trong bộ nhớ đệm của nó.
Tại sao không luôn luôn phục vụ nội dung đã lưu trong bộ nhớ đệm?
Một câu hỏi hay!
Nếu máy khách luôn sử dụng nội dung đã lưu trong bộ nhớ đệm mà không xác thực, họ có thể bỏ lỡ các bản cập nhật hoặc thay đổi cần thiết cho tính đúng đắn. Cơ chế 304 đảm bảo máy khách nhận được tài nguyên cập nhật nếu cần, đồng thời tránh các lần truyền lãng phí nếu không có gì thay đổi.
SEO và 304 Not Modified
Từ góc độ SEO, phản hồi 304 giúp các công cụ tìm kiếm thu thập dữ liệu trang web của bạn hiệu quả hơn. Chúng giảm việc sử dụng băng thông và cải thiện ngân sách thu thập dữ liệu bằng cách phục vụ các phản hồi "không nội dung" cho các trang không thay đổi, cho phép các công cụ tìm kiếm tập trung vào nội dung mới.
Tại sao 304 lại quan trọng đến vậy? Lợi ích
- Thời gian tải cực nhanh: Trình duyệt có thể hiển thị một trang mà không cần chờ tải lại mọi tài sản. Nó có thể sử dụng các phiên bản đã lưu trong bộ nhớ đệm của mình ngay lập tức sau một kiểm tra `304` nhanh chóng.
- Tiết kiệm băng thông lớn: Đây là lợi ích lớn nhất. Phục vụ một phản hồi `304` thay vì `200` với phần thân lớn giúp tiết kiệm một lượng lớn lưu lượng mạng cho cả người dùng và máy chủ.
- Giảm tải máy chủ: Máy chủ tiết kiệm chu kỳ CPU và các hoạt động I/O bằng cách không phải đọc và gửi cùng một tệp từ đĩa hàng nghìn lần mỗi giây.
- Trải nghiệm người dùng tốt hơn: Các trang web nhanh hơn làm cho người dùng hài lòng hơn.
- Giảm chi phí: Đối với các công ty phải trả tiền cho băng thông (như hóa đơn lưu trữ đám mây), việc giảm truyền dữ liệu trực tiếp tiết kiệm tiền.
Các vấn đề thường gặp liên quan đến 304 Not Modified
- ETag/Last-Modified không chính xác hoặc thiếu: Dẫn đến việc máy khách bỏ lỡ các bản cập nhật hoặc tải lại không cần thiết.
- Các tệp tĩnh không được lập phiên bản đúng cách: Ngăn chặn việc xác thực bộ nhớ đệm.
- Proxy hoặc CDN xử lý sai các tiêu đề có điều kiện: Có thể gây ra sự không nhất quán của bộ nhớ đệm.
- Cấu hình máy chủ sai: Trả về 200 OK khi 304 là thích hợp hoặc ngược lại.
Kiểm thử các yêu cầu có điều kiện với Apidog

Kiểm thử hành vi lưu trữ bộ nhớ đệm có thể phức tạp. Bạn cần gửi các yêu cầu với các tiêu đề cụ thể và giải thích phản hồi của máy chủ. Apidog là công cụ hoàn hảo cho việc này.
Với Apidog, bạn có thể:
- Thu thập trình xác thực: Gửi yêu cầu đầu tiên đến một tài nguyên và sử dụng giao diện của Apidog để dễ dàng xem và sao chép các tiêu đề `ETag` và `Last-Modified` từ phản hồi `200`.
- Tạo yêu cầu có điều kiện: Tạo một yêu cầu mới đến cùng URL và dễ dàng thêm các tiêu đề `If-None-Match` hoặc `If-Modified-Since` với các giá trị bạn đã thu thập.
- Xác minh phản hồi 304: Gửi yêu cầu có điều kiện và xác nhận rằng máy chủ trả về trạng thái `304 Not Modified` mà không có phần thân.
- Kiểm thử vô hiệu hóa bộ nhớ đệm: Sửa đổi tài nguyên trên máy chủ (nếu bạn có quyền truy cập) và lặp lại yêu cầu có điều kiện. Bây giờ bạn sẽ thấy một `200 OK` với dữ liệu mới, chứng minh logic lưu trữ bộ nhớ đệm của bạn hoạt động.
- Tự động hóa kiểm thử: Xây dựng các bộ kiểm thử trong Apidog để tự động hóa quy trình này, đảm bảo các tiêu đề lưu trữ bộ nhớ đệm của API của bạn luôn được cấu hình chính xác.
button
Với Apidog, bạn có thể tinh chỉnh việc lưu trữ bộ nhớ đệm mà không cần chờ đợi các trường hợp biên trong thực tế. Tải xuống Apidog miễn phí để khai thác những khả năng này.
Các phương pháp hay nhất cho nhà phát triển
Nếu bạn đang xây dựng một ứng dụng phía máy chủ, bạn có thể tận dụng `304`:
- Luôn gửi trình xác thực: Đối với các tài nguyên có thể lưu vào bộ nhớ đệm (hình ảnh, CSS, JS, dữ liệu API tĩnh), luôn bao gồm tiêu đề `ETag` hoặc `Last-Modified` trong các phản hồi `200` của bạn.
- Triển khai logic có điều kiện: Trong mã máy chủ của bạn, hãy kiểm tra các tiêu đề `If-None-Match` và `If-Modified-Since`. Nếu chúng khớp với tài nguyên hiện tại, hãy phản hồi bằng `304`. Nếu không, hãy phản hồi bằng `200` và dữ liệu mới.
- Sử dụng `Cache-Control`: Tiêu đề `Cache-Control` (ví dụ: `max-age=3600`) cho trình duyệt biết thời gian nó có thể coi một tài nguyên là mới mà không cần phải thực hiện yêu cầu có điều kiện. Điều này thậm chí còn hiệu quả hơn `304`.
304 Not Modified và RESTful API
Trong REST API, 304 nâng cao đáng kể hiệu quả bằng cách cho phép máy khách lưu trữ các biểu diễn tài nguyên. Xử lý bộ nhớ đệm đúng cách giúp giảm tải máy chủ và tăng tốc đồng bộ hóa máy khách.
Trong các API phục vụ các tài nguyên được cập nhật thường xuyên, các yêu cầu có điều kiện với phản hồi 304 là cần thiết cho hiệu suất có khả năng mở rộng.
304 Not Modified trong trình duyệt web
Các trình duyệt hiện đại phụ thuộc rất nhiều vào 304:
- Chrome, Firefox, Safari đều triển khai lưu trữ bộ nhớ đệm dựa trên `ETag` và `Last-Modified`.
- Một lần **làm mới (F5)** vẫn có thể kích hoạt kiểm tra 304.
- Một lần **làm mới cứng (Ctrl + Shift + R)** bỏ qua bộ nhớ đệm, buộc phải có 200.
304 so với 200: Sự khác biệt là gì?
Cả hai mã đều có nghĩa là "thành công", nhưng sự khác biệt nằm ở tải trọng:
- 200 OK → Tài nguyên đầy đủ được trả về.
- 304 Not Modified → Không có tài nguyên nào được trả về, hãy sử dụng bộ nhớ đệm.
Hãy nghĩ về 304 như đang nói:
"Đừng lo, không có gì mới. Cứ tiếp tục sử dụng những gì bạn đã có."
304 so với 200 OK: Khi nào nên chọn gì
- Luôn phục vụ **200 OK** với nội dung đầy đủ trong các yêu cầu đầu tiên hoặc khi nội dung đã thay đổi.
- Chỉ phục vụ **304 Not Modified** khi nội dung chưa thay đổi.
Kiểm soát bộ nhớ đệm đúng cách đảm bảo rằng máy khách biết khi nào cần yêu cầu cập nhật và khi nào nên sử dụng dữ liệu đã lưu trong bộ nhớ đệm.
Kết luận: Người hùng thầm lặng của Web
Mã trạng thái HTTP `304 Not Modified` là một kiệt tác của thiết kế hiệu quả. Nó là một người hùng thầm lặng, hoạt động phía sau hậu trường, làm cho web hiện đại có khả năng mở rộng và nhanh chóng. Nó thể hiện sức mạnh của một giao thức hợp tác nơi máy khách và máy chủ làm việc cùng nhau để tránh công việc không cần thiết.
Mã trạng thái 304 Not Modified có thể không gây chú ý như 404 hoặc 500, nhưng nó rất cần thiết cho hiệu suất, bộ nhớ đệm và hiệu quả. Nó giảm việc sử dụng băng thông, tăng tốc độ tải trang và giữ cho các API hoạt động trơn tru.
Mặc dù người dùng sẽ không bao giờ nhìn thấy nó, nhưng họ trải nghiệm lợi ích của nó mỗi ngày thông qua các trang tải nhanh hơn và duyệt web mượt mà hơn. Đối với các nhà phát triển, việc hiểu và triển khai đúng cách hỗ trợ cho các phản hồi `304` là một kỹ năng quan trọng trong việc tối ưu hóa bất kỳ tài sản web nào.
Vì vậy, lần tới khi một trang tải trong nháy mắt, hãy nhớ đến phản hồi `304` nhỏ bé đã làm cho điều đó có thể. Nếu bạn là nhà phát triển, việc nắm vững 304 có nghĩa là xây dựng các ứng dụng nhanh hơn, thông minh hơn. Hiểu cách triển khai và kiểm thử các phản hồi 304 sẽ nâng cao khả năng của bạn trong việc xây dựng các ứng dụng web và API hiệu quả, hoạt động tốt.
Và hãy nhớ, kiểm thử hành vi lưu trữ bộ nhớ đệm và chuyển hướng dễ dàng hơn bao giờ hết với Apidog một công cụ miễn phí, mạnh mẽ được thiết kế để giúp bạn nắm vững các mã trạng thái HTTP như 304 Not Modified, đừng chỉ tin vào các giả định của bạn, hãy mô phỏng và xác thực việc lưu trữ bộ nhớ đệm với Apidog.
button
