Bạn sẽ không thể thực hiện cuộc gọi ajax đến http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
từ tệp được triển khai tại http://run.jsbin.com
do chính sách nguồn gốc giống nhau .
Vì trang nguồn (hay còn gọi là trang gốc ) và URL mục tiêu nằm ở các tên miền ( run.jsbin.com
và www.ecb.europa.eu
) khác nhau , mã của bạn thực sự đang cố gắng thực hiện một yêu cầu Tên miền chéo (CORS) , không phải là một việc bình thường GET
.
Nói cách khác, chính sách cùng nguồn gốc nói rằng các trình duyệt chỉ nên cho phép các lệnh gọi ajax đến các dịch vụ trên cùng một miền của trang HTML.
Thí dụ:
Một trang tại http://www.example.com/myPage.html
chỉ có thể yêu cầu trực tiếp các dịch vụ tại http://www.example.com
, như http://www.example.com/api/myService
. Nếu dịch vụ được lưu trữ tại một miền khác (giả sử http://www.ok.com/api/myService
), trình duyệt sẽ không thực hiện cuộc gọi trực tiếp (như bạn mong đợi). Thay vào đó, nó sẽ cố gắng thực hiện một yêu cầu CORS.
Nói ngắn gọn, để thực hiện yêu cầu (CORS) * trên các miền khác nhau, trình duyệt của bạn:
- Sẽ bao gồm một
Origin
tiêu đề trong yêu cầu ban đầu (với tên miền của trang là giá trị) và thực hiện nó như bình thường; và sau đó
- Chỉ khi phản hồi của máy chủ cho yêu cầu đó chứa các tiêu đề phù hợp (
Access-Control-Allow-Origin
là một trong số chúng ) cho phép yêu cầu CORS, trình duyệt sẽ hoàn thành lệnh gọi (gần như ** chính xác như cách nó sẽ xảy ra nếu trang HTML ở cùng một miền).
- Nếu các tiêu đề mong đợi không xuất hiện, trình duyệt sẽ bỏ cuộc (giống như nó đã làm với bạn).
* Phần trên mô tả các bước trong một yêu cầu đơn giản , chẳng hạn như một yêu cầu thông thường GET
không có tiêu đề cầu kỳ. Nếu yêu cầu không đơn giản (như loại nội dung POST
với application/json
as), trình duyệt sẽ giữ nó trong giây lát và trước khi thực hiện, trước tiên sẽ gửi OPTIONS
yêu cầu đến URL đích. Giống như ở trên, nó sẽ chỉ tiếp tục nếu phản hồi cho OPTIONS
yêu cầu này có chứa tiêu đề CORS. Cuộc OPTIONS
gọi này được gọi là yêu cầu trước khi bay .
** Tôi đang nói gần như vì có sự khác biệt khác giữa các cuộc gọi thông thường và các cuộc gọi CORS. Một điều quan trọng là một số tiêu đề, ngay cả khi có trong phản hồi, sẽ không được trình duyệt chọn nếu chúng không được đưa vàoAccess-Control-Expose-Headers
tiêu đề.
Làm thế nào để sửa chữa nó?
Nó chỉ là một lỗi đánh máy? Đôi khi mã JavaScript chỉ có lỗi đánh máy trong miền đích. Bạn coi lại chưa? Nếu trang ở www.example.com
đó, nó sẽ chỉ thực hiện các cuộc gọi thông thường đến www.example.com
! Các URL khác, chẳng hạn như api.example.com
hoặc thậm chí example.com
hoặc www.example.com:8080
được trình duyệt coi là các miền khác nhau ! Có, nếu cổng khác, thì đó là một miền khác!
Thêm tiêu đề. Cách đơn giản nhất để kích hoạt CORS là thêm các tiêu đề cần thiết (as Access-Control-Allow-Origin
) vào các phản hồi của máy chủ. (Mỗi máy chủ / ngôn ngữ có một cách để làm điều đó - hãy kiểm tra một số giải pháp tại đây .)
Phương án cuối cùng: Nếu bạn không có quyền truy cập từ phía máy chủ vào dịch vụ, bạn cũng có thể nhân bản nó (thông qua các công cụ như proxy ngược ) và bao gồm tất cả các tiêu đề cần thiết ở đó.