Skip to content
··3 phút đọc

Cơn ác mộng debug HTTP/HTTPS: Hành trình 24 giờ qua địa ngục Mixed Content

Tôi dành 24 giờ debug tại sao React app cứ gửi HTTP request từ trang HTTPS — dù code đang chuyển đổi. Thủ phạm khiến tôi sốc.

---

Cập nhật (Tháng 11/2025): STRAŦUM đã ra mắt Private Alpha! Nền tảng marketing 9 agent nhắc đến trong bài đang nhận tester sớm. Yêu cầu truy cập tại stratum.chandlernguyen.com hoặc đọc câu chuyện launch đầy đủ.

---

Bối cảnh: Hành trình nền tảng marketing tiếp tục

Nhớ bài tháng 9 khi tôi nói đang speed-run nền tảng marketing 10 agent trong khi ngủ trưa? 4 tuần, 3 agent hoạt động, nhắm alpha tháng 10/11.

Giờ cuối tháng 10. Đến lúc cập nhật.

Tin tốt: Nền tảng đã có tên: STRAŦUM (Intelligence Over Execution). 9 trên 10 agent đã xây và tích hợp.

Thực tế: Tôi bị ốm 10 ngày sau khi nghỉ phép 8 ngày. Mọi thứ tạm dừng. Còn gì launch tháng 10, đúng không?

Bài blog này về một trong những khoảnh khắc "build đúng" biến thành marathon debug 6 giờ. Vì ngay khi tôi đang lấy lại tốc độ sau ốm, nền tảng deployment quyết định có kế hoạch khác.

Khi AWS sập, kỹ sư sáng tạo (và đôi khi hối hận)

Thứ Hai bắt đầu thế này. Site production sập, Vercel hiện lỗi do AWS outage diện rộng ảnh hưởng deployment Vercel toàn cầu.

Vào Cloudflare Pages. Migration sang Cloudflare Pages mượt đáng ngạc nhiên. Rồi tôi mở site production.

```
Mixed Content: The page at 'https://my-site.com/...' was loaded over HTTPS,
but requested an insecure resource 'http://stratum-api.us-central1.run.app/...'
```

Cảm giác chìm xuống khi nhận ra ăn mừng hơi sớm? Đó.

Vấn đề: HTTP Call từ trang HTTPS

React app gửi HTTP request đến backend API trong khi trang load qua HTTPS. Trình duyệt (đúng đắn) block vì rủi ro bảo mật. Mixed Content errors. Mọi API call đều fail.

Quá trình debug: Từ biến môi trường đến .gitignore

Tôi kiểm tra biến môi trường Cloudflare — tất cả HTTPS, đúng. Rebuild. Deploy. Vẫn HTTP.

Cập nhật 24 file dùng API_BASE_URL tập trung. Deploy. Vẫn hỏng.

Rồi phát hiện: file api.ts chứa ensureHttpsInProduction() không có trong Git repo! .gitignore có pattern lib/ quá rộng, vô tình ignore cả thư mục frontend lib.

Sửa .gitignore. Thêm file thiếu. Deploy. Vẫn lỗi HTTP.

Khoảnh khắc bừng sáng: File local đang được deploy

Rất muộn trong tối, tôi nhận ra. File .env.production local:

```bash
# apps/web/.env.production (FILE LOCAL)
VITE_API_URL=http://stratum-api.us-central1.run.app
```

Cloudflare Pages deploy file môi trường local thay vì dùng biến dashboard!

Kiểm tra .cloudflare-pages-ignore — thiếu .env.production.

Fix: Một dòng

```diff
# apps/web/.cloudflare-pages-ignore
+.env.production
```

Deploy. Đợi. Lỗi khác! CORS errors! Tuyệt đẹp — nghĩa là HTTPS hoạt động!

Sửa CORS. Deploy. Custom domain vẫn lỗi HTTP — Cloudflare CDN cache aggresive bundle cũ.

Quay về Vercel: Đôi khi nhàm chán là tốt hơn

AWS đã lên lại. Tôi chuyển mọi thứ về Vercel. Deploy 3 phút. Không lỗi HTTP. Không vấn đề cache. Chỉ... hoạt động.

Bài học (theo cách khó)

  1. Luôn ignore .env.production trong deployment platforms
  2. Pattern .gitignore rộng nguy hiểm trong monoreposlib/ ignore cả frontend VÀ backend
  3. Build-time validation vẫn đáng — viết Vite plugin fail build nếu phát hiện HTTP URL trong production
  4. Phòng thủ nhiều lớp hoạt động — Build-time + Runtime + Deployment
  5. Preview URLs là bạn — test preview URL trước custom domain
  6. Biết quirks của platform — Vercel đơn giản hơn, Cloudflare cần purge cache thủ công

Bài học thực sự: Debug là công việc thám tử

Đây không phải vấn đề code. Đây là cuộc khai quật khảo cổ cấu hình.

Giải pháp kỹ thuật là một dòng trong file .ignore. Debug? 6 giờ, 14 deployment, và quá nhiều cà phê.

Bạn đã bao giờ có "fix một dòng" mất thời gian đáng xấu hổ để tìm chưa? Tôi rất muốn nghe câu chuyện debug thám tử — đau khổ cần bạn đồng hành!

Thân mến, Chandler

Đọc tiếp

Hành trình
Kết nối
Ngôn ngữ
Tùy chọn