<tech-stash />
HomeBlogDSASnippetsAbout
Đăng nhập
© 2026 Thai Bao — Tech Stash
BlogSnippetsAboutRSS
Quay lại Blog
corsSecurityAPIBackend

Lỗi CORS là gì? Cách "hóa giải" nỗi ám ảnh kinh hoàng của mọi Frontend

12 tháng 5, 20265 phút đọc

Nếu bạn đã từng code Frontend và gọi API sang một Server khác, chắc chắn 100% bạn đã từng vò đầu bứt tai khi màn hình trắng xóa và tab Console trên trình duyệt hiện lên một dòng chữ đỏ chót đe dọa:

Access to fetch at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Đa số những người mới học sẽ vội vàng lên Google copy một đoạn code nào đó nhét vào Frontend hoặc cài một Extension lách luật trên Chrome để nó chạy cho xong. Nhưng ở góc độ kiến trúc sư phần mềm, nếu không hiểu CORS, hệ thống của bạn sẽ tiềm ẩn những lỗ hổng bảo mật chết người.

1. Nguồn cơn của vấn đề: Chính sách Cùng Nguồn Gốc (SOP)

Để hiểu CORS, trước tiên ta phải nói về SOP (Same-Origin Policy) - Chính sách Cùng Nguồn Gốc. Đây là "Luật phòng vệ" tối thượng được cài đặt sẵn bên trong mọi trình duyệt web (Chrome, Firefox, Safari...).

Origin (Nguồn gốc) là gì? Một Origin được định nghĩa bằng sự kết hợp của 3 yếu tố: Giao thức (Protocol) + Tên miền (Domain) + Cổng (Port). Ví dụ Origin của bạn là: [https://myweb.com:443](https://myweb.com:443)

  • [http://myweb.com](http://myweb.com) => Khác Origin (Khác giao thức)

  • [https://api.myweb.com](https://api.myweb.com) => Khác Origin (Khác Sub-domain)

  • [https://myweb.com:8080](https://myweb.com:8080) => Khác Origin (Khác Port)

Luật SOP quy định: Một trang web chỉ được phép gọi API, đọc dữ liệu từ một Server nếu cả hai có CÙNG NGUỒN GỐC. Nếu Frontend đang chạy ở http://localhost:3000 mà dám gọi API sang http://localhost:8000 (khác Port), trình duyệt sẽ lập tức giương khiên lên đỡ và chặn đứng luồng dữ liệu đó lại.

Tại sao trình duyệt lại gắt gao như vậy? Hãy tưởng tượng bạn đang đăng nhập vào trang web của ngân hàng. Trình duyệt lưu Session Cookie của bạn. Sau đó bạn lỡ tay vào một trang web xem phim lậu. Nếu không có luật SOP, mã độc JavaScript từ trang phim lậu có thể ngầm gọi API sang tên miền của ngân hàng (kèm theo Cookie của bạn) để chuyển tiền đi. Nhờ có SOP, kịch bản này bị bóp nghẹt từ trong trứng nước!

2. CORS: Cuốn "Hộ chiếu" hợp pháp hóa việc vượt biên

Luật SOP bảo vệ người dùng rất tốt, nhưng nó lại gây rắc rối cho các hệ thống phần mềm hiện đại (nơi Frontend chạy một nơi vercel.app, Backend chạy một nẻo aws.com).

Đó là lúc CORS (Cross-Origin Resource Sharing - Chia sẻ tài nguyên chéo) ra đời. CORS là một cơ chế cho phép Backend báo với Trình duyệt rằng: "Ê Trình duyệt, cái tên miền Frontend kia là người nhà của tao đấy, tao cho phép nó đọc dữ liệu, mày hãy thả cửa ra đi!".

3. Cơ chế hoạt động: Cuộc gọi "Thăm dò" (Preflight Request)

Để thực thi CORS, trình duyệt và Server giao tiếp với nhau bằng một cách rất thông minh. Khi Frontend của bạn định gửi một request "nguy hiểm" (như POST, PUT, DELETE, hoặc request có đính kèm Token), trình duyệt sẽ không gửi thẳng request đó đi ngay.

Thay vào đó, nó tạo ra một Preflight Request (Request dọn đường).

  • Bước 1 (Thăm dò): Trình duyệt tự động gửi một request với phương thức OPTIONS lên Server. Nội dung đại khái là: "Tôi là Frontend ở domain-a.com. Tôi định gửi một request POST kèm theo header Authorization. Anh có cho phép không?"

  • Bước 2 (Cấp phép): Server nhận được lời chào, kiểm tra danh sách khách mời. Nếu đồng ý, Server sẽ trả lời bằng các Headers đặc biệt (Bắt đầu bằng chữ Access-Control-...).

  • Bước 3 (Thực thi): Trình duyệt đọc câu trả lời của Server. Thấy có giấy phép hợp lệ, nó mới chính thức gửi request POST thật sự để thêm mới dữ liệu.

Nếu ở Bước 2 Server không trả lời, hoặc trả lời không đúng chuẩn, trình duyệt sẽ giận dỗi, đóng sập cửa lại và quăng cái dòng chữ đỏ chót Blocked by CORS vào mặt Developer.

4. Cách xử lý lỗi CORS triệt để (The Right Way)

Nguyên tắc vàng: Lỗi CORS xảy ra ở Frontend (trình duyệt chặn), nhưng cách sửa đúng đắn nhất phải nằm ở Backend.

Nếu bạn là Frontend Dev, hãy ngừng việc tìm cách "hack" trình duyệt, mà hãy cầm dòng lỗi đó sang nói chuyện với Backend Dev. Backend cần phải cấu hình trả về các Headers sau:

  • 1. Access-Control-Allow-Origin: Xác định ai được phép gọi.

    • Nếu là API public (như thời tiết): Có thể set là * (Cho phép tất cả).

    • Nếu là hệ thống nội bộ: Phải set chính xác tên miền của Frontend (VD: [https://my-frontend.com](https://my-frontend.com)).

  • 2. Access-Control-Allow-Methods: Khai báo các phương thức được phép (VD: GET, POST, PUT, DELETE).

  • 3. Access-Control-Allow-Headers: Khai báo các Custom Headers mà Frontend được phép gửi lên (VD: Content-Type, Authorization).

  • 4. Access-Control-Allow-Credentials: true: (Cực kỳ quan trọng) Nhớ lại bài viết về HttpOnly Cookie không? Nếu bạn muốn trình duyệt tự động đính kèm Cookie gửi lên Server khác tên miền, Backend bắt buộc phải bật cờ này lên true, VÀ Allow-Origin tuyệt đối không được để dấu sao *.

5. Lời kết

CORS không phải là một con bọ (bug), cũng không phải là lỗi của framework bạn đang xài. Nó là một tính năng bảo mật sống còn của nền tảng Web.

Một khi đã hiểu rõ nguyên lý Same-Origin Policy và cơ chế gửi Preflight Request, cái dòng chữ đỏ lòm kia sẽ không còn đáng sợ nữa, mà nó chỉ là một lời nhắc nhở nhẹ nhàng từ trình duyệt rằng bạn cấu hình giấy phép chưa đủ mà thôi!

Bình luận

Đăng nhập để bình luận
Đang tải bình luận...
On this page
  • 1. Nguồn cơn của vấn đề: Chính sách Cùng Nguồn Gốc (SOP)
  • 2. CORS: Cuốn "Hộ chiếu" hợp pháp hóa việc vượt biên
  • 3. Cơ chế hoạt động: Cuộc gọi "Thăm dò" (Preflight Request)
  • 4. Cách xử lý lỗi CORS triệt để (The Right Way)
  • 5. Lời kết