CORS ra đời giúp xác định các nguồn gốc nào được phép truy cập vào domain. Tuy nhiên vấn đề phổ biến mà các nhà phát triển thường gặp phải là lỗi CORS. Lỗi này xảy ra khi nào và tại sao? Cùng tìm hiểu nguyên nhân gây ra lỗi CORS và cách khắc phục một cách an toàn và hiệu quả cùng TopDev.
CORS error là gì?
CORS Error xảy ra khi trình duyệt ngăn chặn một yêu cầu HTTP đến một nguồn (domain) khác với nguồn mà trang web hiện tại đang chạy, do vi phạm các quy tắc bảo mật của Cross-Origin Resource Sharing (CORS). CORS là một tiêu chuẩn bảo mật cho phép máy chủ cho phép hoặc từ chối các yêu cầu từ các nguồn khác nhau.
Nếu cấu hình CORS không được thiết lập đúng cách, trình duyệt sẽ chặn yêu cầu và báo lỗi CORS.
Cách hoạt động của CORS và nguyên nhân gây ra lỗi CORS
CORS cho phép các yêu cầu và việc truyền dữ liệu giữa các trình duyệt và máy chủ có nguồn gốc khác nhau diễn ra một cách an toàn. Cơ chế này dựa vào việc kiểm tra xem liệu máy chủ có cho phép các yêu cầu từ các nguồn gốc khác hay không để đảm bảo rằng các yêu cầu này là an toàn.
Khi một trang web cố gắng thực hiện một yêu cầu cross-origin, trình duyệt sẽ tự động thêm các tiêu đề CORS vào yêu cầu, bao gồm:
Origin
: Nguồn gốc của trang web gửi yêu cầu.Access-Control-Request-Method
: Phương thức HTTP mà yêu cầu sử dụng (như GET, POST).Access-Control-Request-Headers
: Các tiêu đề HTTP bổ sung mà yêu cầu có thể sử dụng.
Đáp lại, máy chủ sẽ gửi phản hồi kèm theo một số tiêu đề CORS để cho phép hoặc chặn yêu cầu, chẳng hạn như:
Access-Control-Allow-Origin
: Xác định nguồn gốc nào được phép truy cập tài nguyên của máy chủ.Access-Control-Allow-Credentials
: Cho biết liệu thông tin xác thực (credentials) có được phép sử dụng hay không.Access-Control-Expose-Headers
: Liệt kê các tiêu đề có thể truy cập từ phía client.Access-Control-Max-Age
: Xác định thời gian mà kết quả của yêu cầu kiểm tra trước (preflight) có thể được lưu trữ trong cache.Access-Control-Allow-Methods
: Chỉ định các phương thức HTTP được phép.Access-Control-Allow-Headers
: Liệt kê các tiêu đề HTTP mà client được phép gửi.
Khi nào xảy ra lỗi CORS?
Lỗi CORS xảy ra khi máy chủ không trả về các tiêu đề CORS cần thiết trong phản hồi. Điều này có thể xảy ra trong các tình huống sau:
-
- Nguồn gốc (Origin) không được phép: Trình duyệt gửi một yêu cầu đến máy chủ khác với một tiêu đề
Origin
chỉ định nguồn gốc của yêu cầu. Nếu máy chủ không trả lại tiêu đềAccess-Control-Allow-Origin
hoặc nếu giá trị của tiêu đề này không khớp với nguồn gốc của yêu cầu, trình duyệt sẽ chặn yêu cầu và gây ra lỗi CORS. - Phương thức HTTP hoặc tiêu đề không được phép: Nếu yêu cầu sử dụng một phương thức HTTP (như PUT, DELETE) hoặc tiêu đề tùy chỉnh mà máy chủ không cho phép (không được chỉ định trong
Access-Control-Allow-Methods
hoặcAccess-Control-Allow-Headers
), trình duyệt sẽ chặn yêu cầu đó. - Yêu cầu Preflight bị từ chối: Khi trình duyệt thực hiện một “preflight request” với phương thức OPTIONS để kiểm tra xem liệu yêu cầu chính có được phép hay không, nếu máy chủ trả về phản hồi không phù hợp (ví dụ không có tiêu đề
Access-Control-Allow-Methods
hoặcAccess-Control-Allow-Origin
hợp lệ), thì yêu cầu chính sẽ bị chặn và một lỗi CORS sẽ xuất hiện.
- Nguồn gốc (Origin) không được phép: Trình duyệt gửi một yêu cầu đến máy chủ khác với một tiêu đề
Ví dụ về lỗi CORS
Giả sử trang web https://domain-a.com
cố gắng thực hiện một yêu cầu API đến https://domain-b.com
. Nếu máy chủ tại https://domain-b.com
không cho phép truy cập từ https://domain-a.com
và không bao gồm https://domain-a.com
trong tiêu đề Access-Control-Allow-Origin
của phản hồi, trình duyệt sẽ chặn yêu cầu này và hiển thị lỗi CORS. Thông báo lỗi CORS thường xuất hiện trong bảng điều khiển của trình duyệt (console), điển hình là:
no ‘access-control-allow-origin’ header is present on the requested resource
Đây chính là lỗi CORS policy mà bất cứ lập trình viên nào cũng sẽ gặp phải. Khi call API tới server mà không có header Access-Control-Allow-Origin
hoặc giá trị của nó không hợp lệ thì sẽ phát sinh lỗi này và không lấy được dữ liệu từ API.
Lỗi này là một biện pháp bảo mật được thiết lập bởi trình duyệt để ngăn chặn các trang web thực hiện yêu cầu không hợp lệ đến các tài nguyên thuộc một miền khác, giúp bảo vệ người dùng khỏi các tấn công như Cross-Site Scripting (XSS) hoặc Cross-Site Request Forgery (CSRF).
Cách khắc phục lỗi trên là phải config enable CORS lên để phía client có thể gọi được dữ liệu. Các bạn có thể tham khảo cách để enable với các ngôn ngữ tại đây Enable CORS on Server
Các loại CORS Error phổ biến
- No ‘Access-Control-Allow-Origin’ header is present on the requested resource: Lỗi này cho biết máy chủ không trả về tiêu đề
Access-Control-Allow-Origin
trong phản hồi, do đó trình duyệt không thể xác định liệu yêu cầu có hợp lệ hay không. - The ‘Access-Control-Allow-Origin’ header has a value ‘…’ that is not equal to the supplied origin: Tiêu đề
Access-Control-Allow-Origin
có giá trị không khớp với nguồn gốc (origin) của yêu cầu. Điều này xảy ra khi máy chủ chỉ cho phép một số nguồn gốc cụ thể truy cập tài nguyên, và nguồn gốc của yêu cầu hiện tại không nằm trong số đó. - CORS policy – Method … is not allowed by Access-Control-Allow-Methods: Phương thức HTTP được sử dụng trong yêu cầu không được máy chủ cho phép. Ví dụ, nếu máy chủ chỉ cho phép các phương thức GET và POST, nhưng yêu cầu sử dụng PUT, thì lỗi này sẽ xảy ra.
- CORS policy – Request header field … is not allowed by Access-Control-Allow-Headers: Một tiêu đề tùy chỉnh được sử dụng trong yêu cầu không được máy chủ cho phép. Điều này xảy ra khi máy chủ không liệt kê tiêu đề đó trong
Access-Control-Allow-Headers
.
Cách khắc phục CORS Error
Cấu hình máy chủ để cho phép CORS
Nếu bạn có quyền truy cập vào dịch vụ backend, bạn có thể cấu hình nó để xử lý các yêu cầu CORS nếu được phép:
- Đảm bảo rằng máy chủ trả về tiêu đề
Access-Control-Allow-Origin
với giá trị chính xác, có thể là một tên miền cụ thể hoặc*
(cho phép tất cả các nguồn gốc). - Xác định rõ ràng các phương thức HTTP được phép trong
Access-Control-Allow-Methods
. - Cho phép các tiêu đề tùy chỉnh cần thiết thông qua
Access-Control-Allow-Headers
.
Trong các ngôn ngữ lập trình khác nhau, có các thư viện và middleware để hỗ trợ việc cấu hình CORS một cách dễ dàng (ví dụ: cors
trong Express.js cho Node.js).
Tuy nhiên, hãy cẩn thận khi sử dụng tùy chọn này vì nó có thể khiến máy chủ của bạn dễ bị tấn công CSRF.
Sử dụng proxy server giúp tránh lỗi CORS
Do Same-Origin Policy được thực thi bởi trình duyệt và không phải là máy chủ, bạn có thể sử dụng một proxy server để gọi API từ xa.
- Proxy server hoạt động như một trung gian giữa client và server. Thay vì thực hiện yêu cầu từ client trực tiếp đến API từ xa, bạn có thể thực hiện yêu cầu đến proxy server. Proxy server sẽ thực hiện yêu cầu đến API từ xa và trả về phản hồi mà nó nhận được từ API đó.
- Bằng cách này, proxy server có thể thêm tiêu đề
Access-Control-Allow-Origin: *
còn thiếu và trả phản hồi cho trình duyệt, giúp tránh lỗi CORS.
Bạn có thể tạo proxy server của riêng mình hoặc sử dụng một proxy server như CORS Anywhere để lấy dữ liệu từ API từ xa. Tuy nhiên, proxy server dùng chung như CORS Anywhere có thể chậm trong một số trường hợp. Nếu bạn cần gọi API từ xa thường xuyên, việc tạo proxy server riêng có thể là một lựa chọn tốt hơn.
Cấu hình CORS trên dịch vụ đám mây
Nếu bạn đang sử dụng các dịch vụ đám mây như AWS S3, Azure Blob Storage, hoặc Google Cloud Storage, bạn cần cấu hình chính sách CORS trực tiếp trên các dịch vụ này để cho phép truy cập từ các nguồn gốc khác nhau.
Bypass the Error Using a Browser Extension
Phương pháp này không phải là giải pháp chính thức để sửa lỗi, nhưng có thể sử dụng trong quá trình phát triển.
Bạn có thể tải xuống một tiện ích mở rộng trình duyệt như CORS Unblock. Tiện ích mở rộng này thêm tiêu đề Access-Control-Allow-Origin: *
vào mỗi phản hồi HTTP khi được kích hoạt.
Cách Browser Extension xử lý lỗi CORS tương tự như việc sử dụng proxy server CORS, nhưng phương pháp này chỉ hoạt động trên máy tính có cài đặt tiện ích mở rộng. Do đó, bạn không nên coi đây là giải pháp chính thức để sửa lỗi CORS và chỉ nên sử dụng nó trong quá trình phát triển.