Mã trạng thái HTTP
Tham khảo đầy đủ các mã trạng thái phản hồi HTTP với các giải thích và các trường hợp sử dụng.
Các danh mục mã trạng thái HTTP
- 1xx (Thông tin) · yêu cầu được nhận, đang xử lý.
- 2xx (Thành công) · yêu cầu được nhận, hiểu và chấp nhận thành công.
- 3xx (Chuyển hướng) · cần một hành động bổ sung để hoàn thành yêu cầu.
- 4xx (Lỗi client) · yêu cầu chứa cú pháp sai hoặc không thể đáp ứng.
- 5xx (Lỗi server) · server không thể đáp ứng một yêu cầu hợp lệ.
Sự khác biệt giữa 301 và 302 là gì?
301 Moved Permanently chỉ ra cho các client rằng tài nguyên đã được di chuyển vĩnh viễn · các công cụ tìm kiếm chuyển xếp hạng. 302 Found là một chuyển hướng tạm thời · URL gốc giữ lại xếp hạng của nó.
Khi nào sử dụng 401 thay vì 403?
401 Unauthorized có nghĩa là «chưa được xác thực» · client phải cung cấp các credentials. 403 Forbidden có nghĩa là «đã được xác thực nhưng không được phép» · các credentials sẽ không thay đổi điều này.
Mã trạng thái 418 có nghĩa là gì?
418 «I'm a teapot» là một trò đùa cá tháng tư từ RFC 2324 (Hyper Text Coffee Pot Control Protocol). Nó không được sử dụng trong thực tế nhưng nổi tiếng trong văn hóa nhà phát triển.
Một Chuẩn Với Ba Thập Kỷ Biến Đổi
Mã trạng thái HTTP đã trải qua nhiều thế hệ đặc tả. RFC 1945 (tháng 5 năm 1996) đã chuẩn hóa HTTP/1.0 với các danh mục 1xx-5xx cơ bản. RFC 2616 (tháng 6 năm 1999) đã phát hành HTTP/1.1 và là tài liệu tham chiếu chuẩn trong hơn một thập kỷ. Bộ 7230-7235 (tháng 6 năm 2014) đã chia HTTP/1.1 thành nhiều đặc tả theo chủ đề. Chuẩn hợp nhất hiện tại là RFC 9110 «HTTP Semantics» (tháng 6 năm 2022), thay thế bộ 7230-7235 và là tài liệu tham chiếu phù hợp cho công việc hiện đại. Sổ đăng ký đầy đủ các mã được gán nằm tại đăng ký mã trạng thái HTTP của IANA.
Năm Danh Mục Tổng Quan
- 1xx Informational: phản hồi tạm thời. Yêu cầu đã được nhận và máy chủ đang tiếp tục xử lý. Hiếm gặp trong thực tế; hữu ích cho các nâng cấp giao thức và mã
103 Early Hintshiện đại (cho phép máy chủ tải trước tài nguyên quan trọng trước khi phản hồi đầy đủ sẵn sàng). - 2xx Success: yêu cầu đã được nhận, hiểu và chấp nhận.
200 OKlà trường hợp thông thường;201 Createdđể tạo tài nguyên;204 No Contentcho các hành động thành công không có gì để trả về. - 3xx Redirection: cần hành động thêm. Các chuyển hướng cổ điển (
301 Moved Permanently,302 Found,307 Temporary Redirect,308 Permanent Redirect) cộng với304 Not Modifiedđể xác thực bộ nhớ đệm. - 4xx Client Error: máy khách đã làm sai điều gì đó: cú pháp không hợp lệ, thiếu xác thực, yêu cầu thứ gì đó không tồn tại. Danh mục lớn nhất trong lưu lượng thực tế.
- 5xx Server Error: máy chủ gặp sự cố. Yêu cầu hợp lệ; máy chủ chỉ không thể xử lý được. Đây là những mã đánh thức kỹ sư trực ca vào ban đêm.
Các So Sánh «vs» Khiến Mọi Người Nhầm Lẫn
401 vs 403. Cặp bị nhầm lẫn nhiều nhất. 401 Unauthorized có nghĩa là «bạn chưa xác thực, hãy thử đăng nhập» (tên này về mặt kỹ thuật gây hiểu nhầm, nó nói về xác thực danh tính, không phải phân quyền). 403 Forbidden có nghĩa là «bạn đã xác thực, nhưng bạn không được phép làm điều này», thông tin đăng nhập hợp lệ nhưng không cấp quyền truy cập tài nguyên này. Lỗi thường gặp: trả về 403 cho các yêu cầu chưa xác thực khi 401 kèm tiêu đề WWW-Authenticate mới là đúng.
301 vs 302 vs 307 vs 308. Hai chiều: vĩnh viễn so với tạm thời, và hành vi bảo toàn phương thức:
| Mã | Vĩnh viễn? | Phương thức được giữ? | Tín hiệu xếp hạng SEO |
|---|---|---|---|
| 301 Moved Permanently | Có | Lịch sử các máy khách đã đổi POST → GET | Vĩnh viễn, chuyển xếp hạng sang URL mới |
| 302 Found | Không | Lịch sử các máy khách đã đổi POST → GET | Tạm thời, URL gốc giữ nguyên xếp hạng |
| 307 Temporary Redirect | Không | Nghiêm ngặt, POST giữ nguyên POST | Giống như 302 |
| 308 Permanent Redirect | Có | Nghiêm ngặt, POST giữ nguyên POST | Giống như 301 |
Nếu bạn đang chuyển hướng các yêu cầu GET cho mục đích SEO, 301 là lựa chọn thông thường. Nếu bạn đang chuyển hướng các yêu cầu POST hoặc PUT và muốn giữ nguyên phương thức, bạn cần 307 hoặc 308.
400 vs 422. 400 Bad Request dành cho các yêu cầu không đúng cú pháp: JSON không hợp lệ, thiếu tiêu đề bắt buộc, tham số truy vấn không hợp lệ. 422 Unprocessable Entity (ban đầu là mã WebDAV, được REST API áp dụng rộng rãi) dành cho các yêu cầu đúng cú pháp nhưng có vấn đề ngữ nghĩa: JSON phân tích đúng nhưng giá trị không qua được xác thực nghiệp vụ (số lượng âm trong đơn hàng, email đã được sử dụng). Nhiều API sử dụng cả hai.
502 vs 503 vs 504. Ba chế độ lỗi upstream khác nhau:
502 Bad Gateway: proxy/gateway đã nhận phản hồi không hợp lệ từ máy chủ upstream.503 Service Unavailable: máy chủ bị quá tải hoặc đang bảo trì. Thường đi kèm tiêu đềRetry-After.504 Gateway Timeout: máy chủ upstream không phản hồi kịp thời.
404 vs 410. 404 Not Found là «chúng tôi không biết tài nguyên này có tồn tại hay không.» 410 Gone là «tài nguyên này từng tồn tại, đã bị xóa vĩnh viễn.» Tác động SEO: Google coi 410 là tín hiệu mạnh hơn rằng nội dung không còn tồn tại vĩnh viễn và xóa khỏi chỉ mục nhanh hơn so với 404.
Quy Ước REST API
Các REST API hiện đại đã hội tụ về một bộ quy ước khá nhất quán về ý nghĩa của mã trạng thái cho từng hành động:
| Phương thức | Trường hợp thành công | Lỗi thường gặp |
|---|---|---|
| GET | 200 OK kèm body, hoặc 304 Not Modified nếu đã được lưu cache | 404 nếu tài nguyên không tồn tại, 403 nếu bị cấm |
| POST (tạo mới) | 201 Created kèm tiêu đề Location trỏ đến tài nguyên mới | 400 cho body không hợp lệ, 422 cho lỗi xác thực, 409 cho xung đột |
| PUT (thay thế) / PATCH (cập nhật) | 200 OK kèm body đã cập nhật, hoặc 204 No Content | 404 nếu tài nguyên không tồn tại, 409 cho xung đột phiên bản |
| DELETE | 204 No Content (hoặc 200 kèm xác nhận xóa) | 404 nếu không tồn tại |
| Bất kỳ (giới hạn tốc độ) | - | 429 Too Many Requests kèm tiêu đề Retry-After |
| Bất kỳ (xác thực) | - | 401 nếu chưa xác thực, 403 nếu đã xác thực nhưng không có quyền |
Tác Động SEO
200 OK: Google lập chỉ mục trang bình thường.301 Moved Permanently: Google cập nhật URL đã lập chỉ mục sang URL mới và chuyển các tín hiệu xếp hạng.302 Found/307 Temporary Redirect: Google giữ URL gốc trong chỉ mục; xếp hạng ở lại với URL gốc.308 Permanent Redirect: Google coi nó giống như 301: xếp hạng được chuyển.304 Not Modified: Googlebot sử dụng cho các yêu cầu có điều kiện; báo hiệu rằng nội dung được lưu cache có thể tái sử dụng.404 Not Found: Google xóa URL khỏi chỉ mục sau một vài lần thu thập dữ liệu.410 Gone: Google xóa URL nhanh hơn so với404; tín hiệu «đã xóa vĩnh viễn» mạnh hơn.503 Service UnavailablekèmRetry-After: yêu cầu Googlebot quay lại sau. Sử dụng trong thời gian bảo trì; tránh dùng503cho các lỗi thực sự (Google hiểu các mã 503 kéo dài là lệnh không thu thập dữ liệu).5xxkéo dài: Google giảm tốc độ thu thập dữ liệu và cuối cùng có thể xóa URL khỏi chỉ mục hoàn toàn.
Các Mã Nổi Tiếng & Văn Hóa
418 I'm a teapot: một trò đùa Cá Tháng Tư từ RFC 2324 (Hyper Text Coffee Pot Control Protocol, ngày 1 tháng 4 năm 1998). Khi IETF đề xuất xóa nó khỏi đặc tả năm 2017, chiến dịch «Save 418» đã thành công giữ lại. Một số API dùng nó như một dấu hiệu «đây không phải thật»; ngoài ra vô hại.451 Unavailable For Legal Reasons: RFC 7725 (2015), đặt theo tên tiểu thuyết Fahrenheit 451 của Ray Bradbury. Được trả về khi nội dung bị kiểm duyệt theo lệnh tòa án hoặc yêu cầu của chính phủ.- Series 520-527 của Cloudflare: không theo chuẩn, được Cloudflare sử dụng để chỉ ra các lỗi kết nối máy chủ upstream cụ thể. Phổ biến khi một trang web phía sau Cloudflare gặp sự cố.
444 No Responsecủa Nginx: đặc thù của Nginx, được trả về khi máy chủ đóng kết nối mà không gửi bất kỳ phản hồi nào.420 Enhance Your Calmlịch sử của Twitter: mã giới hạn tốc độ đã bị xóa, được sử dụng bởi API trước đây của Twitter; đã được thay thế bằng mã chuẩn429.
Các Lỗi Thường Gặp
- Dùng
200 OKcho lỗi kèm body lỗi. Trả về{"error": "not found"}với trạng thái 200 gây nhầm lẫn cho mọi tầng cache, công cụ giám sát và SDK client. Hãy dùng mã trạng thái đúng. - Trả về
403cho các yêu cầu chưa xác thực. Mã đúng là401kèm tiêu đềWWW-Authenticate. - Dùng
302khi bạn muốn dùng301. Nếu việc di chuyển là vĩnh viễn, công cụ tìm kiếm cần301để chuyển xếp hạng.302giữ URL cũ trong chỉ mục. - Dùng
301hoặc302cho các chuyển hướng POST/PUT. Trong lịch sử, các mã này cho phép máy khách đổi phương thức sang GET.307và308bảo toàn nghiêm ngặt phương thức gốc. - Trả về
500khi bạn muốn dùng503. Nếu máy chủ bị quá tải hoặc đang bảo trì,503kèmRetry-Afterlà tín hiệu đúng, cho cả máy khách lẫn Googlebot. - Dùng
404cho các trang đã bị xóa vĩnh viễn.410 Gonelà tín hiệu mạnh hơn và được xóa khỏi chỉ mục công cụ tìm kiếm nhanh hơn. - Quên tiêu đề
Locationtrong các phản hồi201và3xx. Tiêu đềLocationlà thứ cho máy khách biết tài nguyên mới ở đâu hoặc nơi cần chuyển hướng. Nếu không có nó, máy khách không thể điều hướng.
Câu Hỏi Thường Gặp Thêm
Khi nào nên trả về 422 thay vì 400?
400 Bad Request có nghĩa là chính yêu cầu bị lỗi định dạng: JSON không hợp lệ, thiếu tiêu đề bắt buộc, tham số truy vấn không hợp lệ. 422 Unprocessable Entity có nghĩa là yêu cầu đúng định dạng nhưng chứa lỗi ngữ nghĩa ngăn xử lý: trường số lượng đặt về số âm, địa chỉ email đã được sử dụng, ngày trong quá khứ cho trường chỉ chấp nhận tương lai. Quy ước REST API hiện đại đã hội tụ về cách phân chia này, với hầu hết các API lớn (GitHub, Stripe, Twilio) sử dụng 422 cho lỗi xác thực.
Tại sao Cloudflare đôi khi trả về 520, 521, 522…?
Các mã 520-527 là đặc thù của Cloudflare, báo hiệu các cách khác nhau mà edge của họ không thể kết nối đến máy chủ gốc của bạn. 520 là lỗi chung «máy chủ web trả về lỗi không xác định»; 521 có nghĩa là máy chủ gốc của bạn từ chối kết nối; 522 là timeout kết nối đến máy chủ gốc; 524 có nghĩa là máy chủ gốc của bạn phản hồi quá chậm. Chúng không có trong IANA registry nhưng thường gặp khi các trang web phía sau Cloudflare có vấn đề backend.
Trình duyệt có hiển thị mã nào API của tôi trả về không?
Có, mở DevTools → tab Network, nhấp vào yêu cầu và xem cột «Status». Trình duyệt cũng hiển thị các trang chung cho một số mã (trò chơi khủng long trên các lỗi kết nối Chrome, các trang 404/500 chuẩn); nhưng mã số thực tế luôn có trong phản hồi.
103 Early Hints là gì?
Mã 1xx tương đối mới (RFC 8297, 2017) cho phép máy chủ gửi tiêu đề Link: rel=preload trước khi phản hồi đầy đủ sẵn sàng, yêu cầu trình duyệt bắt đầu tải về các tài nguyên quan trọng (CSS, font, hình ảnh) sớm hơn. Hiện được Chrome hỗ trợ và triển khai bởi Cloudflare, Fastly và các CDN khác như một tối ưu hóa hiệu suất.
Tôi có thể tự tạo mã trạng thái riêng không?
Về mặt kỹ thuật là có (HTTP cho phép bất kỳ mã 3 chữ số nào trong phạm vi 100-599, nhưng thực tế là không nên), máy khách, proxy và cache xử lý các mã không xác định theo chữ số đầu tiên (nên 4xx = lỗi máy khách nói chung, 5xx = lỗi máy chủ). Một số nhà cung cấp làm điều này (520s của Cloudflare, 444 của Nginx), nhưng trừ khi bạn kiểm soát cả hai đầu kết nối, hãy tuân theo IANA registry. Tự đặt ra 299 sẽ không gây lỗi nhưng cũng không truyền đạt được gì.
Tại sao «status code» được gọi là «status» chứ không phải «error code»?
Vì hầu hết chúng không phải là lỗi. 200 OK là mã trạng thái được trả về nhiều nhất trên thế giới, nghĩa là «mọi thứ đều ổn.» Các mã này truyền đạt trạng thái của yêu cầu: thành công, chuyển hướng, lỗi máy khách, lỗi máy chủ. Gọi chúng là «error codes» sẽ thiên về các trường hợp tiêu cực được ghi log và chú ý; các mã thành công đang thực hiện công việc của chúng một cách im lặng mỗi micro giây.