Vấn đề gặp phải khi mình phải code 1 con server để upload ảnh và trả về url. Code xong xuôi, test trên postman chạy ok nhưng khi ốp vào client vkt thì tạch:
1 2 3 |
XMLHttpRequest cannot load http://localhost:3000/upload. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. |
- Nguồn gốc vấn đề
Same-Origin Policy: một biện pháp bảo mật an ninh hạn chế sự tương tác giua 2 document có nguồn gốc khác nhau.Về cơ bản, đây là một chính sách quy định nội dung từ một website chỉ được đọc và thay đổi bởi một thành phần khác cùng site đấy, trường hợp truy cập nằm ngoài phạm vi site sẽ bị chặn.Nếu không có SOP, khi người dùng vô tình truy cập một trang web độc hại, script được đặt sẵn trên này có thể truy cập được dữ liệu và thực hiện tính năng của bất kỳ trang web nào người dùng đã dùng trước đóNguôn gốc ở đây được xác định bởi: protocol, host và port.Một ứng dụng web trên một domain:
• có thể gửi request đến một domain khác (chẳng hạn việc submit form) nhưng tự nó không thể parse dữ liệu được trả về.
• có thể tải script từ một domain khác và thực thi ngay tại domain mình. Điều này do script thuộc loại code (mã lập trình) chứ không chỉ là data (dữ liệu) nên không dẫn đến việc lộ lọt thông tin nhạy cảm.
• không thể đọc hoặc chỉnh sửa cookie của domain khác.Server mình viêt chạy ở localhost:3000, client vkt chạy ở localhost:8080 => bị SOP block. - Giai pháp:
Sử dụng Cross Origin Resource Sharing CORS cung cấp 1 giai pháp cho server để “nhắn” tới client rằng: “OK, thằng domain A có thể đọc data từ thằng domain B” bằng cách thêmAccess-Control-Allow-Origin HTTP header vào response.Trong trường hợp con server nodejs của mình thì cần thêm 1 midleware như sau:
123456789app.use(function (req, res, next) {res.setHeader('Access-Control-Allow-Origin', '*');res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');res.setHeader('Access-Control-Allow-Headers', 'Content-type');res.setHeader('Access-Control-Allow-Headers', 'X-Signature');res.setHeader('Access-Control-Allow-Headers', 'X-Key');next();});
Dấu * kia khá nguy hiểm (như mình đếch care 🙁 ) vì nó cho phép mọi client khác đọc được response khi request đên server.