Khi phát triển web, bạn từng gặp lỗi “No ‘Access-Control-Allow-Origin’ header is present on the requested resource” trên console trình duyệt? Đó chính là lúc CORS – Cross-Origin Resource Sharing – can thiệp. CORS là cơ chế bảo mật quan trọng do trình duyệt áp dụng để kiểm soát việc chia sẻ tài nguyên giữa các nguồn gốc khác nhau. Hiểu rõ cors là gì không chỉ giúp bạn debug nhanh hơn mà còn tối ưu kiến trúc bảo mật cho ứng dụng web hiện đại.
Khái niệm cốt lõi: CORS là gì và tại sao nó tồn tại?

CORS (Cross-Origin Resource Sharing) là một cơ chế dựa trên HTTP header cho phép máy chủ chỉ định những nguồn gốc (origin) nào được phép truy cập tài nguyên từ trang web khác. Nói đơn giản, khi bạn chạy JavaScript trên domain A và gọi API từ domain B, trình duyệt sẽ tự động kiểm tra header CORS trước khi cho phép đọc dữ liệu.
Mục đích chính của CORS là giải quyết hạn chế của Same-Origin Policy (SOP) – chính sách bảo mật ngăn chặn một trang web truy cập dữ liệu từ một trang web khác. SOP được thiết kế để chống các cuộc tấn công XSS và CSRF, nhưng gây khó khăn cho các ứng dụng web hiện đại cần gọi API từ nhiều nguồn khác nhau.
Origin được xác định bởi ba thành phần: scheme (protocol), host (domain) và port. Ví dụ, https://example.com:443 là một origin hoàn chỉnh. Hai URL có cùng scheme và host nhưng khác port được coi là cross-origin.
Cơ chế hoạt động của CORS
Simple requests vs Preflight requests
CORS phân loại HTTP request thành hai loại: simple request và preflight request.
Simple request thỏa mãn đồng thời ba điều kiện:
- Phương thức là GET, HEAD hoặc POST
- Headers chỉ bao gồm các header an toàn như Accept, Accept-Language, Content-Language, Content-Type với giá trị application/x-www-form-urlencoded, multipart/form-data, hoặc text/plain
- Không dùng ReadableStream hay đối tượng XMLHttpRequest upload
- Access-Control-Request-Method: phương thức sẽ dùng (ví dụ PUT)
- Access-Control-Request-Headers: danh sách header không an toàn
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- Access-Control-Max-Age (tùy chọn) – thời gian cache preflight response
- Bảo mật nâng cao: CORS cho phép server chủ động kiểm soát truy cập từ các origin khác, ngăn chặn khai thác dữ liệu trái phép
- Hỗ trợ kiến trúc microservices: Cho phép frontend gọi API từ nhiều domain khác nhau dễ dàng
- Linh hoạt: Server có thể cấp quyền cho một số origin cụ thể, cho phép credential (cookie/token) mà vẫn đảm bảo an toàn
- Tương thích CDN và third-party services: Tích hợp API từ Google, Facebook, Stripe… mà không cần proxy
- Phức tạp trong debug: Lỗi CORS thường khó phát hiện vì không phải lỗi HTTP thực sự mà do trình duyệt chặn
- Không thể áp dụng cho tất cả trình duyệt cũ: IE8, IE9 không hỗ trợ CORS đầy đủ (chỉ dùng XDomainRequest)
- Thêm latency từ preflight: Mỗi request phức tạp phải gửi thêm một OPTIONS request, tăng độ trễ
- Rủi ro bảo mật nếu cấu hình sai: Dùng wildcard () với credentials là lỗi nghiêm trọng
Khi simple request được gửi từ origin A đến origin B, trình duyệt tự động thêm header Origin: https://origin-a.com. Máy chủ B phản hồi với header Access-Control-Allow-Origin chứa giá trị phù hợp. Nếu không, trình duyệt block phản hồi và báo lỗi CORS.
Preflight request xảy ra khi request không phải simple – thường là PUT, DELETE, PATCH, hoặc có custom header như Authorization, X-Requested-With. Trình duyệt gửi một request OPTIONS trước (preflight) để hỏi máy chủ có chấp nhận request thật không.
Preflight request chứa các header:
Máy chủ phải trả về header tương ứng:
Các HTTP header CORS quan trọng
| Header | Mô tả | Role |
|---|---|---|
| Access-Control-Allow-Origin | Xác định origin được phép (hoặc cho tất cả) | Response header |
| Access-Control-Allow-Credentials | Cho phép gửi cookie/xác thực cùng request | Response header |
| Access-Control-Expose-Headers | Cho phép client truy cập các header cụ thể từ response | Response header |
| Access-Control-Allow-Methods | Liệt kê phương thức HTTP được phép | Response header (preflight) |
| Access-Control-Allow-Headers | Liệt kê header không an toàn được phép | Response header (preflight) |
| Access-Control-Max-Age | Cache preflight response trong bao lâu (giây) | Response header (preflight) |
| Origin | Origin của request (tự động thêm bởi trình duyệt) | Request header |
| Access-Control-Request-Method | Phương thức sẽ dùng trong request thật | Request header (preflight) |
| Access-Control-Request-Headers | Header không an toàn sẽ dùng trong request thật | Request header (preflight) |
Lợi ích và hạn chế của CORS

















