304 — Nội dung không thay đổi

HTTP 304 Not Modified là gì, vì sao đây là mã 3xx nhưng không phải chuyển hướng, cách ETag và Last-Modified vận hành, cùng lợi ích gián tiếp cho hiệu quả crawl trên site lớn mà không ảnh hưởng thứ hạng.

Xuất bản lần đầu: 3 thg 7, 2026 · Cập nhật lần cuối: 22 thg 8, 2026 · Advanced
Ngôn ngữ
1 tín hiệu bằng chứng trên trang này

HTTP 304 Not Modified là phản hồi cho yêu cầu GET hoặc HEAD có điều kiện khi điều kiện được đánh giá false và nếu không có điều kiện sẽ nhận 200. Đây là phản hồi lớp 3xx nhưng không phải chuyển hướng: không có header Location và theo đặc tả hoàn toàn không có body. GET/HEAD mang If-None-Match để so với ETag hoặc If-Modified-Since để so với Last-Modified chính là yêu cầu có điều kiện; lần truy cập thứ hai chỉ là ví dụ thường gặp, không phải quy tắc giao thức. Khi validator còn khớp, máy chủ trả 304 không body và client dùng bản cache. SEO không có tác động trực tiếp đến thứ hạng; Google đã có nội dung và 304 chỉ xác nhận chưa đổi, dù Search có thể tính lại tín hiệu URL. Trên site lớn có nhiều URL ít thay đổi, 304 tiết kiệm băng thông và khả năng tính toán, điều Google nói có thể gián tiếp cải thiện hiệu quả crawl nhưng không bảo đảm tự động phân bổ crawl budget sang URL khác. Google khuyên ưu tiên ETag vì không có cạm bẫy định dạng ngày, đồng thời hỗ trợ đặt cả hai validator. Chỉ làm cache mất hiệu lực khi nội dung thật sự thay đổi đáng kể, không phải chỉ đổi năm bản quyền ở footer. Đừng nhầm 304 với 301/302/307/308 đưa client sang URL khác hoặc 204 No Content cũng không body nhưng vì thật sự không có gì để gửi.

Tóm tắt — 304 là phản hồi cho yêu cầu GET/HEAD có điều kiện khi điều kiện được đánh giá false và nếu không có điều kiện thì sẽ nhận 200 (RFC 9110 §15.4.5). Nó thuộc lớp 3xx nhưng không phải chuyển hướng: không Location, không URL mới và theo quy chuẩn không có body — “it cannot contain content or trailers” (bản dịch) «không được chứa nội dung hoặc trailer». Điều kiện đi qua If-None-Match so với ETag và/hoặc If-Modified-Since so với Last-Modified; nếu validator còn khớp, máy chủ trả 304 và client dùng lại cache. SEO: không có tác động trực tiếp đến thứ hạng; Google đã có nội dung dù Search vẫn có thể tính lại tín hiệu URL. Trên site lớn, tiết kiệm tài nguyên có thể gián tiếp cải thiện hiệu quả crawl, nhưng Google không hứa tự động phân bổ crawl budget sang URL khác. Hạ tầng crawl Google hỗ trợ cả hai validator và khuyên ưu tiên ETag vì tránh lỗi định dạng ngày. Đừng nhầm 304 với 301/302/307/308 chuyển URL hoặc 204 không có body vì thật sự không có gì để gửi.

Ý nghĩa của 304 trong đặc tả

RFC 9110 (HTTP Semantics) §15.4.5 định nghĩa chính xác: “The 304 (Not Modified) status code indicates that a conditional GET or HEAD request has been received and would have resulted in a 200 (OK) response if it were not for the fact that the condition evaluated to false.” (bản dịch) «Mã 304 cho biết đã nhận yêu cầu GET hoặc HEAD có điều kiện; nếu điều kiện không được đánh giá là false thì yêu cầu đó sẽ dẫn đến phản hồi 200.» Đây là tác nhân mang tính quy chuẩn. Nói đơn giản, client hỏi “chỉ gửi trang nếu nó đổi”, máy chủ xác định chưa đổi nên bỏ qua body. “Lần truy cập thứ hai” là ví dụ thường ngày về cách yêu cầu trở thành có điều kiện, không phải yêu cầu của giao thức; đặc tả chỉ đòi hỏi yêu cầu có điều kiện. Evidence for this claim RFC 9110 defines 304 Not Modified as the response to a conditional GET or HEAD when the selected representation has not changed and says the response cannot contain content. Scope: HTTP semantics for 304 conditional responses. Confidence: high · Verified: IETF: RFC 9110 §15.4.5 — 304 Not Modified

Đặc tả thậm chí dùng từ “redirecting”: “the server is therefore redirecting the client to make use of that stored representation as if it were the content of a 200 (OK) response” (bản dịch) «máy chủ hướng client dùng biểu diễn đã lưu như thể đó là nội dung của phản hồi 200». Hãy đọc kỹ: client được hướng về cache của chính nó, không phải URL khác. Không có header Location hay địa chỉ mới. Câu này là nguồn của phần lớn nhầm lẫn rằng 304 là chuyển hướng; theo nghĩa HTTP, nó không phải.

Hai điểm quy chuẩn khác cũng quan trọng:

  • Không bao giờ có body. RFC 9110 viết: “A 304 response is terminated by the end of the header section; it cannot contain content or trailers.” (bản dịch) «Phản hồi 304 kết thúc ở cuối phần header; nó không được chứa nội dung hoặc trailer.» 304 có body vi phạm đặc tả và một số client sẽ xử lý sai. Đây là quy tắc bắt buộc.
  • Mang cùng metadata mà 200 sẽ gửi. Máy chủ “MUST generate any of the following header fields that would have been sent in a 200 (OK) response to the same request: Content-Location, Date, ETag, and Vary” (bản dịch) «PHẢI tạo các trường header tương ứng vốn sẽ được gửi trong phản hồi 200 cho cùng yêu cầu: Content-Location, Date, ETag và Vary», cùng Cache-ControlExpires khi áp dụng. Có thể hiểu 304 là các header của 200 không kèm payload. Evidence for this claim A 304 response terminates after the header section and cannot contain content or trailers. Scope: conditional GET and HEAD Confidence: high · Verified: RFC 9110 §15.4.5: 304 Not Modified

304 hoạt động thế nào: yêu cầu có điều kiện

Máy chủ không tự nhiên gửi 304. Nó luôn trả lời một yêu cầu có điều kiện, tức yêu cầu mà client gắn một validator đã lưu từ phản hồi trước. Có hai loại validator.

ETag và If-None-Match

ETag (entity tag) là token opaque mà máy chủ gắn vào phản hồi 200; hãy coi nó như dấu vân tay phiên bản của đúng biểu diễn URL đó. Trong yêu cầu tiếp theo, client gửi lại giá trị bằng header If-None-Match. Nếu ETag hiện tại vẫn khớp, nội dung chưa đổi và máy chủ trả 304; nếu khác, máy chủ trả 200 mới với nội dung và ETag mới.

Last-Modified và If-Modified-Since

Phương án dựa trên ngày: máy chủ gửi timestamp Last-Modified trong phản hồi 200. Lần sau client gửi lại bằng If-Modified-Since; nếu tài nguyên chưa thay đổi kể từ mốc đó, kết quả là 304. Cách này đơn giản nhưng kém chi tiết hơn và nhạy với định dạng HTTP-date chính xác, một nguồn lỗi phổ biến. Khi có cả hai validator, If-None-Match (ETag) được ưu tiên hơn If-Modified-Since.

ETag mạnh và yếu

ETag có thể mạnh hoặc yếu. Theo hướng dẫn yêu cầu có điều kiện của MDN, “strong validation consists of guaranteeing that the resource is, byte to byte, identical to the one it is compared to.” (bản dịch) «xác thực mạnh bảo đảm tài nguyên giống hệt từng byte với tài nguyên được so sánh». ETag yếu có tiền tố W/, ví dụ ETag: W/"abc123", và chỉ khẳng định tương đương ngữ nghĩa. Ví dụ của MDN coi hai trang chỉ khác ngày ở footer hoặc quảng cáo là giống nhau theo xác thực yếu. ETag mạnh không có tiền tố và cần cho range request đòi hỏi khớp byte chính xác; ETag yếu hữu ích khi nén, khoảng trắng hoặc khác biệt vụn vặt không nên buộc tải lại toàn bộ. Cạm bẫy thực tế là ETag đổi mỗi lần nén gzip/Brotli hoặc khác giữa các máy chủ cân bằng tải sẽ gây crawl lại không cần thiết. Hãy chủ ý chọn loại validator và giữ ổn định khi nội dung thật sự không đổi.

Toàn bộ quá trình bắt tay

  1. Yêu cầu đầu → máy chủ trả 200 OK với nội dung cùng ETag và/hoặc Last-Modified.
  2. Client lưu nội dung và validator.
  3. Yêu cầu sau → client gửi If-None-Match và/hoặc If-Modified-Since với giá trị đã lưu.
  4. Máy chủ quyết định: chưa đổi → 304 Not Modified, không body, client dùng cache; đã đổi → 200 OK với body và validator mới. Evidence for this claim RFC 9111 defines validation as checking whether a stored response remains current, typically with a conditional request that can receive 304 Not Modified. Scope: HTTP cache validation; it does not create a Search ranking benefit. Confidence: high · Verified: IETF: RFC 9111 §4.3 — Validation

Nếu cần phân tích sâu hơn về cache và validator như đòn bẩy hiệu quả crawl, gồm toàn bộ câu chuyện yêu cầu có điều kiện và quan hệ với crawl budget, hãy xem chủ đề đi kèm; bài này tập trung vào mã trạng thái.

304 và SEO: không ảnh hưởng thứ hạng, có lợi cho hiệu quả crawl

Câu chuyện SEO hẹp hơn nhiều nội dung chung trên blog. 304 không có tác động trực tiếp đến thứ hạng; hướng dẫn của Google cũng giới hạn tác động lập chỉ mục: Search có thể vẫn tính lại tín hiệu của URL, nhưng ngoài điều đó 304 không thay đổi cách trang được lập chỉ mục. Google đã có nội dung từ lần crawl trước; 304 chỉ xác nhận chưa đổi. Không có phần thưởng xếp hạng cho việc trả 304.

Lợi ích của 304 là tiết kiệm tài nguyên, từ đó có thể gián tiếp cải thiện hiệu quả crawl. Trong bài Search Central tháng 12/2024 về HTTP caching, Gary Illyes viết: “Especially if you have a large site with rarely-changing content under individual URLs, allowing caching locally may help your site be crawled more efficiently. Google’s crawling infrastructure supports heuristic HTTP caching as defined by the HTTP caching standard, specifically through the ETag response- and If-None-Match request header, and the Last-Modified response- and If-Modified-Since request header.” (bản dịch) «Đặc biệt với site lớn có nội dung hiếm thay đổi ở từng URL, cho phép cache cục bộ có thể giúp site được crawl hiệu quả hơn. Hạ tầng crawl của Google hỗ trợ HTTP caching suy đoán theo tiêu chuẩn, cụ thể qua ETag/If-None-Match và Last-Modified/If-Modified-Since.»

Về cơ chế 304, cùng bài viết giải thích vì sao body rỗng là trọng tâm: nếu ETag crawler gửi “matches the current value the server generated, your server should return an HTTP 304 (Not modified) status code with no HTTP body” (bản dịch) «khớp giá trị hiện tại do máy chủ tạo, máy chủ nên trả HTTP 304 không có body». Không tạo và truyền body giúp tiết kiệm tính toán cùng băng thông ở cả hai phía. Google dùng ngôn ngữ có điều kiện: tiết kiệm đó có thể gián tiếp cải thiện hiệu quả crawl. Đây không phải lời hứa rằng công sức tiết kiệm được sẽ tự động chuyển sang URL mới hay đã cập nhật.

Vì sao site lớn hưởng lợi hơn

Với vài trăm trang, lợi ích phần lớn mang tính học thuật vì Google có thể crawl toàn site dễ dàng. Giá trị tăng theo quy mô: site có hàng trăm nghìn hoặc hàng triệu URL, nhiều URL hiếm thay đổi, hưởng lợi đáng kể khi crawler bỏ qua việc tải lại nội dung cũ. Đó là đối tượng bài Google nhắm đến; đừng quảng bá quá mức 304 như chiến thuật cho site nhỏ.

Chọn ETag hay Last-Modified và thế nào là “đã đổi”

Google khuyên dùng ETag làm validator chính: “We strongly recommend using ETag because it’s less prone to errors and mistakes (the value is not structured unlike the Last-Modified value).” (bản dịch) «Chúng tôi đặc biệt khuyên dùng ETag vì ít dễ mắc lỗi hơn; giá trị không có cấu trúc như Last-Modified.» Có thể và nên đặt cả hai. Nếu dùng Last-Modified, ngày “must be formatted according to the HTTP standard” (bản dịch) «phải được định dạng theo tiêu chuẩn HTTP». Google đề xuất mẫu “Weekday, DD Mon YYYY HH:MM:SS Timezone,” (bản dịch) «Thứ, ngày tháng năm giờ:phút:giây múi giờ», ví dụ “Fri, 4 Sep 1998 19:15:56 GMT”, nếu không header có thể bị bỏ qua. Google cũng gợi ý đặt max-age của Cache-Control để giúp crawler quyết định thời điểm crawl lại. Evidence for this claim Google's crawler guidance recommends ETag because its opaque value avoids date-formatting errors, while also allowing both ETag and Last-Modified; this is Google-specific operational advice, not a change to HTTP validator semantics. Scope: HTTP cache validation Confidence: high · Verified: Crawling December: HTTP caching

Bạn quyết định thay đổi nào đáng làm cache mất hiệu lực. Google khuyên chỉ làm mới khi nội dung thay đổi đáng kể: “Our recommendation is that you require a cache refresh on significant changes to your content; if you only updated the copyright date at the bottom of your page, that’s probably not significant.” (bản dịch) «Hãy yêu cầu làm mới cache khi nội dung thay đổi đáng kể; nếu chỉ cập nhật ngày bản quyền ở cuối trang thì có lẽ chưa đáng kể.»

Googlebot và Bingbot thực sự làm gì

Không phải mọi yêu cầu crawler đều có điều kiện. Tài liệu crawler Google nói mức hỗ trợ cache khác nhau theo crawler và sản phẩm: Googlebot hỗ trợ cache khi crawl lại URL cho Search, còn một số fetcher khác chỉ hỗ trợ trong điều kiện nhất định. Vì vậy, dù header đúng, đừng mong 100% yêu cầu có If-None-Match hoặc If-Modified-Since. Yêu cầu có điều kiện cũng không riêng Google. Crawler Bing đã hỗ trợ conditional GET, gửi If-Modified-Since và khi có thì If-None-Match, rồi chấp nhận 304 khi nội dung chưa đổi, ít nhất từ bài Live Search năm 2008. Tuy Bing chưa có bài hiện đại tương đương tài liệu Google năm 2024, hãy coi đây là hành vi HTTP chung áp dụng cho cả hai công cụ.

Cách triển khai hỗ trợ 304

  1. Gửi validator trong phản hồi 200. Cấu hình máy chủ, CDN hoặc ứng dụng gắn ETag (được khuyên dùng) và/hoặc Last-Modified đúng định dạng vào phản hồi 200. Nhiều máy chủ và framework tự tạo ETag cho file tĩnh; phản hồi động thường cần bật rõ.
  2. Tôn trọng header có điều kiện khi yêu cầu quay lại. Khi nhận If-None-Match/If-Modified-Since, so sánh với validator hiện tại; trả 304 không body nếu còn khớp hoặc 200 mới nếu không. Máy chủ file tĩnh thường tự làm, còn route ứng dụng và edge worker thường cần cấu hình.
  3. Xác định thế nào là “đã đổi” và giữ ETag ổn định cho nội dung thật sự không đổi; đừng để nén lại hay khác biệt giữa máy chủ làm nó đổi vô ích.
  4. Theo dõi các cấu hình sai kinh điển:
    • Luôn trả 200 — không phát validator nên không yêu cầu nào có điều kiện và mất lợi ích hiệu quả.
    • ETag không ổn định — giá trị đổi dù nội dung không đổi, như do cân bằng tải hoặc nén lại, buộc tải lại liên tục.
    • 304 cũ — nguy hiểm nhất: máy chủ tiếp tục trả 304 hoặc ETag cũ sau khi nội dung thật sự đổi, khiến crawler và cache không nhận bản cập nhật. Đây là lỗi cần phát hiện trong phân tích log, không phải khuyết điểm vốn có của 304.

So sánh 304 với mã trạng thái khác

304 với 301 / 302 / 307 / 308

Các mã kia mới là chuyển hướng thật. 301/308 vĩnh viễn hoặc 302/307 tạm thời mang header Location và đưa client đến URL khác; 301/308 còn truyền tín hiệu canonical hóa. 304 không có Location, không di chuyển ai và không truyền tín hiệu xếp hạng. Cùng họ 3xx về số nhưng nhiệm vụ hoàn toàn khác. Chi tiết từng mã nằm trong bài riêng, gồm chuyển hướng 301 và trang trung tâm chuyển hướng.

304 với 204 No Content

Cả hai đều không body nhưng vì lý do hoàn toàn khác. 204 No Content là thành công 2xx với body cố ý rỗng vì máy chủ thật sự không có gì để gửi, như API DELETE/PUT thành công hoặc analytics beacon. 304 cũng không body, nhưng vì “bạn đã có nội dung và nó vẫn hợp lệ”. Đừng đánh đồng: 204 trên URL trang có thể bị coi như soft 404 vì không có nội dung để lập chỉ mục; 304 xác nhận hiệu lực của nội dung Google đã có. Bài 204 No Content trình bày đầy đủ mã đó.

Quan niệm sai phổ biến về 304

  1. “304 là chuyển hướng.” Không có header Location và không ai đi đâu; client dùng lại cache. Cụm “redirecting the client to make use of that stored representation” (bản dịch) «hướng client dùng biểu diễn đã lưu» trong RFC 9110 nói về cache, không phải URL khác.
  2. “304 là lỗi cần sửa.” Đây là kết quả đúng của yêu cầu có điều kiện. Thấy 304 trong crawl hoặc DevTools thường nghĩa là cache hoạt động.
  3. “304 giúp thứ hạng.” Không có tác động trực tiếp đến thứ hạng; Search có thể tính lại tín hiệu URL nhưng 304 không thay đổi việc lập chỉ mục theo cách khác. Lợi ích là tiết kiệm tài nguyên, có thể gián tiếp cải thiện hiệu quả crawl trên site rất lớn, không phải tín hiệu xếp hạng hay cam kết chuyển công sức sang URL khác.
  4. “If my server returns 304, Google will use stale content forever.” (bản dịch) «Nếu máy chủ trả 304, Google sẽ dùng nội dung cũ mãi.» Không đúng: 304 chỉ xuất hiện khi validator còn khớp. Khi nội dung đổi, triển khai đúng sẽ trả 200 mới cùng validator mới. Rủi ro thật là máy chủ cấu hình sai vẫn trả 304 sau thay đổi. Evidence for this claim RFC 9111 defines validation as checking whether a stored response remains current, typically with a conditional request that can receive 304 Not Modified. Scope: HTTP cache validation; it does not create a Search ranking benefit. Confidence: high · Verified: IETF: RFC 9111 §4.3 — Validation
  5. “ETag và Last-Modified có thể thay thế hoàn toàn cho nhau.” Cả hai là validator, nhưng Last-Modified nhạy với định dạng ngày và chỉ chi tiết đến timestamp; ETag opaque và chính xác hơn, dù có thể khác giữa máy chủ hoặc sau nén lại nếu triển khai bất cẩn. Google khuyên ưu tiên ETag và dùng cả hai nếu có thể.

Câu hỏi thường gặp

HTTP 304 có phải lỗi không? Không. Đây là tín hiệu thành công cho biết cache hoạt động và bản sao của client vẫn hợp lệ.

304 Not Modified có phải chuyển hướng không? Không. Nó thuộc lớp 3xx theo cách đánh số nhưng không có header Location và không đưa client đến URL mới.

304 có giúp SEO hoặc thứ hạng không? Không có tác động trực tiếp đến thứ hạng và không ảnh hưởng lập chỉ mục ngoài khả năng Google tính lại tín hiệu URL. Nó tiết kiệm băng thông và khả năng tính toán khi crawler bỏ qua trang chưa đổi; Google nói điều này có thể gián tiếp cải thiện hiệu quả crawl trên site lớn.

ETag khác Last-Modified thế nào? ETag là dấu vân tay phiên bản opaque được so bằng If-None-Match; Last-Modified là timestamp được so bằng If-Modified-Since. Google khuyên dùng ETag vì ít dễ lỗi hơn.

ETag yếu khác ETag mạnh thế nào? ETag mạnh khẳng định nội dung giống từng byte; ETag yếu có tiền tố W/ khẳng định tương đương ngữ nghĩa và chấp nhận khác biệt nhỏ như nén hoặc ngày ở footer.

Vì sao log hoặc báo cáo crawl có 304? Vì client gửi yêu cầu có điều kiện và máy chủ xác nhận đúng rằng nội dung chưa đổi. Đây là hành vi mong đợi và có lợi.

Làm sao để máy chủ trả 304 đúng? Gửi ETag/Last-Modified trong 200, rồi tôn trọng If-None-Match/If-Modified-Since ở yêu cầu sau bằng cách trả 304 không body khi validator còn khớp.

304 khác 204 thế nào? Cả hai không body; 204 vì không có gì để gửi, 304 vì client đã có một bản sao vẫn hợp lệ.

Googlebot có gửi header có điều kiện trong mọi yêu cầu không? Không. Mức hỗ trợ cache khác nhau theo crawler nên không phải yêu cầu nào cũng có điều kiện dù header được cấu hình đúng.

Phản hồi 304 có thể có body không? Không. RFC 9110 ghi “it cannot contain content or trailers” (bản dịch) «nó không được chứa nội dung hoặc trailer». 304 có body là vi phạm đặc tả. Evidence for this claim A 304 response terminates after the header section and cannot contain content or trailers. Scope: conditional GET and HEAD Confidence: high · Verified: RFC 9110 §15.4.5: 304 Not Modified

Try it live

This is a real endpoint on this site — not a simulation. Hit it from the button, open it in a new tab, or curl -i it from your terminal, and the server answers with the actual status code this article is about.

Open in new tab ↗

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.