Một bộ công cụ nhỏ để gỡ lỗi chuyển hướng và HTTP headers trong production
Năm công cụ dòng lệnh và kỹ thuật trên trình duyệt giúp bạn thấy điều gì thực sự đang diễn ra giữa client và server
Mục lục
Vấn đề khi gỡ lỗi HTTP trong production
Hầu hết sự cố HTTP đều vô hình trong trình duyệt. Một chuỗi chuyển hướng lỗi mà không báo rõ, một cache header sai chỉ một ký tự, một chính sách CORS chặn request mà không giải thích. Công cụ phát triển của trình duyệt cho bạn thấy kết quả của cuộc trao đổi, nhưng chúng thường che đi phần trao đổi thô đã gây ra vấn đề.
Điều này quan trọng nhất trong production, nơi bạn không thể thêm logging hoặc khởi động lại dịch vụ chỉ để xem điều gì đã thay đổi. Bạn cần các công cụ cho thấy cuộc trao đổi HTTP thực tế: request headers, response headers, status codes, redirect targets, timing. Dưới đây là năm công cụ làm tốt việc đó một cách đáng tin cậy, cùng với các kỹ thuật trên trình duyệt để bổ trợ cho chúng.
curl: nền tảng
curl là công cụ đầu tiên nên dùng vì nó cho bạn thấy chính xác server đã gửi gì, không có lớp diễn giải của trình duyệt ở giữa.
Để xem response headers mà không tải body:
curl -I https://example.com
Để đi theo các chuyển hướng và xem từng bước:
curl -L -v https://example.com
Cờ -v (verbose) hiển thị đầy đủ request và response, bao gồm tất cả headers. Cờ -L tự động đi theo các chuyển hướng. Kết hợp lại, chúng cho bạn thấy toàn bộ chuỗi chuyển hướng, nơi phần lớn sự cố production thường xuất hiện.
Để chỉ xem các vị trí chuyển hướng:
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" -L https://example.com
Cách này hữu ích khi bạn cần xác minh một chuỗi chuyển hướng mà không bị nhiễu bởi toàn bộ headers. Cờ -w định dạng output để chỉ hiển thị status code và URL tiếp theo trong chuỗi.
curl cũng cho phép bạn gửi custom headers, điều rất cần thiết khi kiểm thử hành vi CDN, xác thực hoặc API endpoints:
curl -H "Authorization: Bearer token" -H "Accept: application/json" https://api.example.com
httpie: curl với mặc định dễ dùng hơn
httpie là một công cụ Python làm những việc curl làm, nhưng có cú pháp dễ nhớ hơn và output dễ đọc hơn. Nó không phải là sự thay thế—curl mạnh hơn và được cài sẵn rộng rãi hơn—nhưng với các kiểm tra nhanh, httpie nhanh hơn.
Để xem headers:
http HEAD https://example.com
Để đi theo chuyển hướng:
http --follow --all https://example.com
Cờ --all hiển thị mọi response trong chuỗi chuyển hướng, không chỉ response cuối cùng. Đây là tương đương với curl -L -v, nhưng output được tô màu và dễ quét hơn.
Để gửi JSON:
http POST https://api.example.com name=value
httpie mặc định giả định JSON, giúp tiết kiệm thao tác gõ khi bạn kiểm thử API. Nó cũng pretty-print response, giúp dễ phát hiện headers sai định dạng hoặc giá trị bất ngờ.
Browser DevTools: tab Network
Tab Network của trình duyệt là nơi bạn nên bắt đầu nếu sự cố chỉ xảy ra trong trình duyệt. Nó cho bạn thấy cùng loại thông tin như curl, nhưng cũng cho thấy cách trình duyệt diễn giải: liệu nó có chặn request không, xử lý caching ra sao, có gửi cookies hay không.
Để xem đầy đủ request và response headers, nhấp vào bất kỳ request nào trong tab Network, rồi xem phần Headers. Chế độ xem "Raw" hiển thị headers đúng như khi chúng được gửi, không có định dạng lại.
Để xem chuỗi chuyển hướng, hãy tìm các request có status codes 3xx. Trình duyệt nhóm chúng dưới request cuối cùng, nhưng bạn có thể mở rộng để xem từng bước. Đây là nơi bạn sẽ tìm thấy redirect loops, thiếu Location headers, hoặc các chuyển hướng trỏ đến sai domain.
Để xem timing, hãy xem tab Timing của bất kỳ request nào. Phần này cho biết trình duyệt đã dành bao lâu cho DNS lookup, TCP connection, TLS handshake và chờ server. Nếu một chuyển hướng chậm, tab timing cho bạn biết vấn đề nằm ở network latency hay server processing.
Một hạn chế: trình duyệt ẩn một số headers vì lý do bảo mật. Set-Cookie headers có thể thấy được, nhưng giá trị cookie thực tế bị che. Authorization headers đôi khi bị ẩn hoàn toàn. Nếu bạn cần xem những phần đó, hãy dùng curl.
mitmproxy: proxy chặn giữa
mitmproxy là một công cụ Python nằm giữa trình duyệt của bạn và server, cho bạn thấy mọi request và response theo thời gian thực. Nó phức tạp hơn curl, nhưng là công cụ duy nhất cho bạn thấy trình duyệt thực sự gửi gì, bao gồm các headers mà trình duyệt tự động thêm vào.
Để khởi động:
mitmproxy
Sau đó cấu hình trình duyệt của bạn dùng localhost:8080 làm HTTP proxy. mitmproxy sẽ hiển thị mọi request trong giao diện terminal. Bạn có thể kiểm tra headers, chỉnh sửa request trước khi gửi, hoặc replay request với tham số khác.
Điều này hữu ích khi gỡ lỗi những vấn đề chỉ xảy ra trong trình duyệt: CORS preflight requests, xử lý cookie, hoặc request thất bại khi có một số headers nhất định. Nó cũng hữu ích để kiểm thử cách site của bạn hoạt động phía sau corporate proxy hoặc VPN, vì mitmproxy có thể mô phỏng các môi trường đó.
Nhược điểm là độ phức tạp khi thiết lập. Bạn cần cài đặt root certificate để mitmproxy có thể chặn HTTPS traffic, và cần cấu hình trình duyệt dùng proxy. Với kiểm tra nhanh, curl nhanh hơn. Với gỡ lỗi sâu, mitmproxy đáng để đầu tư thời gian thiết lập.
webpagetest: góc nhìn production
WebPageTest là một dịch vụ miễn phí tải trang của bạn từ các trình duyệt thật ở nhiều vị trí khác nhau và cho bạn thấy toàn bộ cuộc trao đổi HTTP. Nó chậm hơn curl, nhưng cho thấy trải nghiệm của người dùng thực, bao gồm hành vi CDN, DNS resolution và TLS negotiation.
Các chế độ xem "Request Headers" và "Response Headers" cho bạn thấy chính xác trình duyệt đã gửi và nhận gì. Chế độ xem "Waterfall" cho bạn thấy timing của mọi request, bao gồm các chuyển hướng. Đây là nơi bạn sẽ tìm thấy những vấn đề chỉ xảy ra ở một số khu vực hoặc trên một số mạng nhất định.
WebPageTest cũng cho bạn thấy chuỗi chuyển hướng của tài liệu chính, nơi phần lớn vấn đề redirect thường xuất hiện. Nếu site của bạn chuyển hướng từ http:// sang https://, rồi từ www. sang non-www., rồi từ / sang /en/, WebPageTest cho bạn thấy cả ba bước và thời gian của từng bước.
Đối với các công cụ giúp bạn xác thực và tối ưu các nền tảng HTTP này, Wux Webtools cung cấp nhiều tiện ích chạy hoàn toàn trong trình duyệt của bạn, bao gồm header analyzers và redirect checkers tôn trọng quyền riêng tư bằng cách xử lý mọi thứ phía client.
Khi headers nói dối
Những vấn đề HTTP khó nhất là khi server gửi các headers mâu thuẫn. Một Cache-Control header nói no-cache, nhưng một Expires header nói tài nguyên hợp lệ trong một năm. Một Location header trỏ đến URL tương đối, nhưng Content-Location header lại trỏ đến nơi khác. Trình duyệt phải đoán nên tin cái nào, và các trình duyệt khác nhau có thể đoán khác nhau.
Khi điều này xảy ra, bạn cần xem headers thô theo đúng thứ tự server đã gửi. curl -v làm được việc này. mitmproxy cũng vậy. DevTools của trình duyệt đôi khi sắp xếp lại headers để dễ đọc, và điều đó che mất vấn đề.
Một vấn đề phổ biến khác: headers được thêm bởi CDN hoặc load balancer, không phải bởi ứng dụng của bạn. Nếu bạn đang gỡ lỗi một vấn đề caching, bạn cần biết Cache-Control header đến từ app hay từ CDN. curl cho bạn thấy kết quả cuối cùng, nhưng không cho biết từng header đến từ đâu. Để làm việc đó, bạn cần bypass CDN (bằng cách gọi trực tiếp origin server) và so sánh headers.
Vấn đề redirect loop
Redirect loops là vấn đề HTTP phổ biến nhất trong production. Chúng xảy ra khi hai server không thống nhất URL nên trỏ đến đâu: CDN chuyển hướng đến origin, origin lại chuyển hướng về CDN. Hoặc load balancer chuyển hướng HTTP sang HTTPS, nhưng app lại chuyển hướng HTTPS về HTTP vì nó không thấy X-Forwarded-Proto header.
Để gỡ lỗi việc này, bạn cần xem toàn bộ chuỗi chuyển hướng, bao gồm Location header ở từng bước. curl -L -v làm được việc này, nhưng nó dừng sau 50 lần chuyển hướng để tránh vòng lặp vô hạn. Nếu bạn chạm đến giới hạn đó, bạn đang có một redirect loop.
Cách sửa thường là thay đổi cấu hình: yêu cầu app tin tưởng X-Forwarded-Proto header, hoặc yêu cầu CDN ngừng chuyển hướng các request vốn đã là HTTPS. Nhưng bạn không thể sửa cho đến khi nhìn thấy vòng lặp, và trình duyệt sẽ không cho bạn thấy quá vài lần chuyển hướng trước khi bỏ cuộc.
Nên kiểm tra gì trước
Khi có gì đó lỗi trong production, hãy kiểm tra theo thứ tự sau:
- Status code: Nó có đúng như bạn mong đợi không? 301 là vĩnh viễn, 302 là tạm thời, 307 giữ nguyên HTTP method. Nếu bạn thấy sai code, vấn đề nằm trong cấu hình chuyển hướng.
- Location header: Nó có trỏ đúng nơi không? Đó là URL tuyệt đối hay tương đối? URL tương đối được resolve dựa trên URL hiện tại, điều có thể tạo ra kết quả bất ngờ nếu base URL không phải như bạn nghĩ.
- Cache headers: Trình duyệt có đang cache chuyển hướng không? Chuyển hướng 301 được cache theo mặc định, nghĩa là một chuyển hướng cấu hình sai có thể làm hỏng site của bạn trong nhiều giờ ngay cả sau khi bạn đã sửa. Kiểm tra
Cache-ControlvàExpiresheaders để biết trình duyệt sẽ ghi nhớ chuyển hướng trong bao lâu.
- CORS headers: Nếu request là cross-origin, server có gửi đúng
Access-Control-Allow-Originheader không? Nếu không, trình duyệt sẽ chặn request, và bạn sẽ thấy lỗi CORS trong console. Response headers của server là nơi duy nhất để sửa việc này—bạn không thể workaround trong trình duyệt.
- Timing: Request mất bao lâu? Nếu chậm, đó là network latency hay server processing? DevTools của trình duyệt và WebPageTest đều cho bạn thấy phân rã timing để biết thời gian đã đi đâu.
Để xem sâu hơn cách hành vi trình duyệt đã thay đổi quanh quyền riêng tư và headers, hãy xem điều gì đã thay đổi với cookies trong năm 2026 và bạn nên làm gì, bài viết trình bày các hệ quả về header và consent từ những cập nhật trình duyệt gần đây.
Những điểm chính
curl -L -vcho bạn thấy toàn bộ chuỗi chuyển hướng và tất cả headers, không có diễn giải của trình duyệt- Tab Network của trình duyệt cho bạn thấy trình duyệt đã làm gì với response, bao gồm các quyết định caching và CORS
mitmproxycho bạn thấy trình duyệt đã gửi gì, bao gồm các headers mà trình duyệt tự động thêm vào- WebPageTest cho bạn thấy trải nghiệm của người dùng thực, bao gồm hành vi CDN và khác biệt theo khu vực
- Redirect loops và headers mâu thuẫn là những vấn đề production phổ biến nhất, và chúng vô hình nếu không kiểm tra HTTP thô
FAQ
Hỏi: Vì sao curl hiển thị headers khác với trình duyệt?
Đáp: Vì trình duyệt tự động thêm headers (User-Agent, Accept, Cookie) và tuân theo các quy tắc riêng cho caching và CORS. curl chỉ gửi những gì bạn yêu cầu nó gửi. Để xem trình duyệt thực sự gửi gì, hãy dùng mitmproxy hoặc DevTools của trình duyệt.
Hỏi: Làm thế nào để gỡ lỗi một chuyển hướng chỉ xảy ra với một số người dùng?
Đáp: Kiểm tra xem chuyển hướng có phụ thuộc vào headers mà người dùng gửi không: User-Agent, Accept-Language, Cookie, hoặc địa chỉ IP (qua X-Forwarded-For). Dùng curl để gửi cùng headers mà người dùng đã gửi, hoặc dùng WebPageTest để tải trang từ vị trí của người dùng.
Hỏi: Sự khác nhau giữa chuyển hướng 301 và 302 là gì?
Đáp: 301 là vĩnh viễn và yêu cầu trình duyệt cache chuyển hướng (đôi khi là mãi mãi). 302 là tạm thời và yêu cầu trình duyệt không cache nó. Nếu bạn không chắc nên dùng cái nào, hãy dùng 302—bạn luôn có thể đổi sang 301 sau.
Hỏi: Vì sao chuyển hướng của tôi hoạt động trong curl nhưng không hoạt động trong trình duyệt?
Đáp: Có thể vì trình duyệt đang cache một chuyển hướng cũ, hoặc vì trình duyệt đang chặn chuyển hướng do quy tắc CORS hoặc mixed content. Kiểm tra console trong DevTools của trình duyệt để xem lỗi, và kiểm tra Cache-Control headers để biết trình duyệt có đang dùng response đã cache hay không.
Hỏi: Làm thế nào để xem headers mà CDN thêm vào?
Đáp: Dùng curl để gọi CDN URL, rồi dùng curl lần nữa để gọi trực tiếp origin server (bypass CDN). So sánh headers. Những header chỉ xuất hiện trong response đầu tiên là do CDN thêm vào.
<!-- tool-cta:start -->
💡 Hãy thử cách này: Khi truy tìm các sự cố chuyển hướng, Redirect Checker theo dõi toàn bộ chuỗi và hiển thị mã trạng thái cùng tiêu đề ở mỗi bước chuyển.
<!-- tool-cta:end -->
Nguồn
- Tài liệu curl — Tham chiếu chính thức cho các tùy chọn dòng lệnh và hành vi của curl
- Tài liệu HTTPie — Hướng dẫn về cú pháp và tính năng của httpie
- MDN Web Docs: HTTP redirections — Giải thích toàn diện về status codes và hành vi chuyển hướng HTTP
- Tài liệu WebPageTest — Cách diễn giải kết quả và headers trong WebPageTest


