Technical SEO

Cross-Origin Resource Sharing (CORS)

Cơ chế kiểm soát quyền truy cập tài nguyên giữa các nguồn gốc khác nhau, ảnh hưởng đến khả năng tải font, API, hoặc tài nguyên bên ngoài.

4 lượt xem Cập nhật: 30/05/2026

Cross-Origin Resource Sharing (CORS) là gì?

Cross-Origin Resource Sharing (CORS) là cơ chế bảo mật do trình duyệt áp dụng để kiểm soát việc một trang web từ miền (origin) này có được phép tải hoặc tương tác với tài nguyên từ miền khác hay không. Origin bao gồm giao thức (http/https), tên miền và cổng — ví dụ: https://example.comhttps://api.example.com là hai origin khác nhau vì tên miền khác nhau; http://site.comhttps://site.com cũng khác origin do giao thức khác.

CORS không phải là công nghệ mới, mà là tập hợp các tiêu đề HTTP (HTTP headers) do máy chủ gửi về để thông báo cho trình duyệt biết tài nguyên nào được phép chia sẻ với nguồn gốc nào. Cơ chế này không ảnh hưởng đến yêu cầu server-to-server — chỉ áp dụng khi JavaScript trong trình duyệt cố gắng gọi API, tải font, hình ảnh, script hoặc dữ liệu từ domain khác.

Tại sao quan trọng trong SEO?

CORS ảnh hưởng trực tiếp đến trải nghiệm người dùng và khả năng thu thập dữ liệu của công cụ tìm kiếm — đặc biệt khi trang web phụ thuộc vào tài nguyên bên ngoài:

  • Tải font chữ: Nếu font từ CDN (ví dụ Google Fonts, Adobe Fonts) bị chặn do cấu hình CORS sai, trình duyệt sẽ không hiển thị đúng kiểu chữ → làm chậm rendering, gây CLS (Cumulative Layout Shift) cao → ảnh hưởng điểm Core Web Vitals.
  • Gọi API động: Trang sử dụng JavaScript để lấy nội dung (ví dụ bài viết từ headless CMS) nhưng API không bật CORS → dữ liệu không hiện → nội dung trống khi thu thập (crawler không chạy JS như người dùng thật, nhưng nếu dùng SSR hoặc hybrid thì lỗi vẫn gây hỏng dữ liệu).
  • Hình ảnh/video từ CDN: Nếu thẻ <img> hoặc <video> trỏ tới domain khác mà không có crossorigin phù hợp, trình duyệt có thể bỏ qua việc tải metadata (như kích thước, thời lượng) → ảnh hưởng đến lazy loading và xử lý responsive.
  • Lỗi console không hiển thị rõ ràng cho crawler, nhưng làm tăng tỷ lệ thoát, giảm thời gian ở lại — yếu tố gián tiếp ảnh hưởng xếp hạng.

Cách hoạt động

Khi JavaScript trên https://site-a.com gọi fetch('https://api.site-b.com/data'), trình duyệt thực hiện theo quy trình sau:

  1. Nếu yêu cầu đơn giản (GET/POST với header chuẩn, không có cookie), trình duyệt gửi request luôn — nhưng chỉ cho phép đọc phản hồi nếu máy chủ trả về header Access-Control-Allow-Origin phù hợp.
  2. Với yêu cầu phức tạp (có header tùy chỉnh như Authorization, phương thức PUT/DELETE, hoặc gửi cookie), trình duyệt gửi trước một preflight request bằng phương thức OPTIONS để hỏi máy chủ: "Tôi có được phép gửi yêu cầu này không?".
  3. Máy chủ phải trả lời với các header như:
    Access-Control-Allow-Origin: https://site-a.com (hoặc * nếu cho phép tất cả)
    Access-Control-Allow-Methods: GET, POST, OPTIONS
    Access-Control-Allow-Headers: Content-Type, Authorization
    Access-Control-Allow-Credentials: true (nếu cần gửi cookie)
  4. Nếu preflight thành công, trình duyệt mới gửi yêu cầu chính. Ngược lại, lỗi Blocked by CORS policy xuất hiện trong Console.

Hướng dẫn thực hiện

Để bật CORS đúng cách cho website hoặc API, bạn cần cấu hình ở phía máy chủ — không thể sửa bằng HTML hay JavaScript thuần:

  1. Xác định origin được phép: Chỉ liệt kê domain cụ thể (ví dụ https://domain.com) thay vì dùng * nếu có gửi cookie hoặc xác thực.
  2. Cấu hình header bắt buộc:
    • Access-Control-Allow-Origin: giá trị duy nhất, không được đặt nhiều domain cùng lúc.
    • Access-Control-Allow-Methods: liệt kê phương thức được phép (phân tách bằng dấu phẩy).
    • Access-Control-Allow-Headers: liệt kê header client được phép gửi.
  3. Thêm hỗ trợ preflight: Đảm bảo endpoint OPTIONS trả về status 200 và đầy đủ header kể trên.
  4. Cookie & xác thực: Nếu cần gửi cookie, thêm Access-Control-Allow-Credentials: truekhông dùng * cho Access-Control-Allow-Origin — phải ghi rõ domain.
  5. Kiểm tra thực tế: Dùng curl -I -H "Origin: https://test.com" https://api.yoursite.com để xem header trả về.

Lỗi thường gặp

Lỗi Nguyên nhân Cách khắc phục
No 'Access-Control-Allow-Origin' header Máy chủ không trả về header CORS hoặc trả về sai cú pháp. Thêm header Access-Control-Allow-Origin vào response (Apache: Header set Access-Control-Allow-Origin "https://yourdomain.com"; Nginx: add_header Access-Control-Allow-Origin "https://yourdomain.com";).
Credentials flag is true + Origin is '*' Dùng Access-Control-Allow-Credentials: true nhưng Access-Control-Allow-Origin*. Thay * bằng domain cụ thể, hoặc bỏ credentials: true nếu không cần cookie.
Preflight response doesn't pass access control check Endpoint OPTIONS không tồn tại hoặc không trả đúng header. Cấu hình route OPTIONS trả về status 200 + đầy đủ header Allow-Origin, Allow-Methods, Allow-Headers.

Ví dụ thực tế

Vấn đề: Một trang blog dùng font từ https://fonts.googleapis.com, nhưng do thẻ <link> thiếu thuộc tính crossorigin, trình duyệt không tải được font fallback → văn bản hiển thị sai, gây layout shift.

Giải pháp:

  • Sửa thẻ link thành: <link href="https://fonts.googleapis.com/css2?family=Roboto" rel="stylesheet" crossorigin>
  • Đảm bảo CDN font đã cấu hình sẵn CORS — Google Fonts hỗ trợ sẵn nên không cần thay đổi server.

Vấn đề khác: Website thương mại điện tử gọi API sản phẩm từ https://api.shop.vn nhưng API trả Access-Control-Allow-Origin: * và không hỗ trợ credentials. Khi người dùng đăng nhập, giỏ hàng không đồng bộ.

Giải pháp: Cập nhật API để trả Access-Control-Allow-Origin: https://shop.vnAccess-Control-Allow-Credentials: true, đồng thời frontend gọi fetch với { credentials: 'include' }.

Câu hỏi thường gặp

CORS có ảnh hưởng đến Googlebot không?

Googlebot không áp dụng chính sách CORS vì nó không chạy JavaScript như trình duyệt người dùng. Tuy nhiên, nếu lỗi CORS khiến nội dung không render được (ví dụ: dữ liệu từ API không hiện ra trong HTML tĩnh), thì Googlebot sẽ thu thập trang thiếu nội dung — ảnh hưởng trực tiếp đến SEO. Với trang dùng SSR hoặc SSG, vấn đề này ít xảy ra hơn.

Có thể tắt CORS trong trình duyệt để test không?

Không nên — việc chạy Chrome với flag --disable-web-security chỉ dành cho môi trường local, không phản ánh hành vi thực tế của người dùng hoặc crawler. Kết quả test như vậy không đáng tin cậy cho đánh giá SEO.

CDN có cần cấu hình CORS riêng không?

Có. Mỗi CDN (Cloudflare, CloudFront, BunnyCDN…) đều cho phép thiết lập header tùy chỉnh. Nếu bạn lưu font, JS hoặc ảnh trên CDN và truy cập từ domain khác, cần bật Access-Control-Allow-Origin tại mức CDN — không chỉ ở origin server. Cách cấu hình tùy CDN, có thể thay đổi qua dashboard hoặc file cấu hình.