2013-10-30 15 views
11

Tôi đã dành 3 ngày cuối cùng để nghiên cứu cách thực hiện yêu cầu miền chéo bằng cách sử dụng XMLHttpRequest. Cách thay thế tốt nhất thực sự là với JSONP mà tôi đã sử dụng.Chính sách xuất xứ tương tự XMLHttpRequest

Nhưng tôi vẫn có một câu hỏi mà tôi không thể tìm thấy câu trả lời ở đâu cả. Tôi đọc hàng trăm bài viết (bao gồm cả SO) và không ai có một câu trả lời đáng tin cậy (với tham chiếu tốt đẹp). Hy vọng ai đó ở đây có thể giúp đỡ.

Nói rằng, tôi đọc ở nhiều trang web vì lý do bảo mật, tôi không thể thực hiện yêu cầu Ajax từ miền aaa.com sang bbb.com và nhận dữ liệu tôi muốn. Nó rất rõ ràng và tôi không có câu hỏi về điều đó. NHƯNG vấn đề là khi tôi chạy mã dưới đây trong localhost của tôi (vì vậy tên miền của tôi là "localhost" và tôi không nên tôi có thể yêu cầu bất kỳ dữ liệu từ một tên miền khác).

xhReq = new XMLHttpRequest(); 
xhReq.open("GET","http://domain.com?parameter",true); 
xhReq.send(null); 

Khi tôi kiểm tra tab Firebug Net Tôi nhận thấy yêu cầu không bị chặn! Nó được yêu cầu rõ ràng. Tôi đã không thể tin được. Vì vậy, tôi đã tạo một tệp trong domain.com/log.php nơi tôi có thể ghi lại bất kỳ yêu cầu nào đã nhấn vào tên miền của mình. Đáng ngạc nhiên là tất cả các yêu cầu tôi đã kích hoạt localhost đều đã nhấn domain.com của tôi. Khi tôi cố gắng tìm nạp câu trả lời, tôi thực sự không thể nhận được do chính sách gốc của trình duyệt Chrome và FIrebug của tôi. Nhưng tôi đã rất ngạc nhiên khi yêu cầu thực sự nhấn máy chủ web mặc dù tôi không thể thao túng người trả lời.

Đáng ngạc nhiên hơn là nếu domain.com/log.php tạo ra một phản hồi rất lớn với 1MB con bọ lửa của tôi cho tôi thấy trình duyệt tải xuống tất cả 1MB từ máy chủ web và cuối cùng nó hiển thị thông báo "Truy cập bị từ chối " như mong đợi. Vậy tại sao phải tải xuống tất cả tệp nếu chính sách gốc giống nhau cấm dữ liệu đó được đọc.

Cuối cùng, tôi làm tôi kinh ngạc, là tất cả các trang web và thông số kỹ thuật tôi đọc nói rất rõ ràng rằng yêu cầu bị chặn bằng cách sử dụng Ajax khi tên miền đích không khớp với miền nguồn. Nhưng rõ ràng, với thử nghiệm của tôi, các yêu cầu đang được hoàn thành, mặc dù tôi không thể truy cập vào dữ liệu phản hồi. Điều khiến tôi khó chịu là nó có thể mở một lỗ hổng bảo mật lớn, trong đó một trang web với hàng nghìn lượt xem hàng ngày có thể chạy mã 3 dòng này và gây ra một cuộc tấn công Ddos HUGE trong một trang web không thân thiện, khiến người dùng yêu cầu trang trong một trang web khác trong khoảng thời gian nhỏ vì trình duyệt sẽ không chặn yêu cầu.

Tôi đã thử nghiệm tập lệnh này trong IE 7, 8 và 9 và Chrome mới nhất và Firefox mới nhất và hành vi là như nhau: yêu cầu được thực hiện và trình duyệt tải xuống tất cả phản hồi trong khi không thể thực hiện SOP.

Hy vọng ai đó có thể giải thích cho tôi lý do thông số kỹ thuật sai về điều đó hoặc những gì tôi hiểu sai!

+0

đẹp câu hỏi. Không biết tại sao yêu cầu lại nhấn tên miền ngoài. Tôi đã làm một thử nghiệm ở đây và như bạn, yêu cầu đã được hoàn thành tuy nhiên tôi không thể lấy câu trả lời. Hy vọng ai đó giúp. – amandanovaes

+0

Bạn có thể kiểm tra xem 'domain.com' có [CORS] (http://www.w3.org/TR/cors/) được bật hay không .... nhưng nếu IE không hoạt động ... bất kỳ cách nào bạn có thể xác nhận –

+0

@ArunPJohny no, CORS không được bật. Đó là một trang web ví dụ. Bạn có thể thay đổi domain.com thành bất kỳ tên miền nào và bạn sẽ thấy trong Firebug hoặc Chrome Net Console rằng yêu cầu được hoàn thành mà không có lỗi. Rõ ràng đây không phải là lỗi gây ra tất cả trình duyệt mà tôi đã thử nghiệm hoạt động theo cùng một cách, nhưng tại sao đặc tả lại nói rằng yêu cầu "bị chặn" đối với yêu cầu ajax miền chéo. – Samul

Trả lời

1

Điều này xảy ra bởi vì các chính sách có nguồn gốc tương tự được áp dụng trên các mặt hàng (trình duyệt) bằng cách đánh giá các tiêu đề kiểm soát truy cập sau các giá trị trở từ máy chủ:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Phương pháp
  • Access-Control-Allow-Headers

Như bạn thấy, yêu cầu trước tiên phải được hoàn thành trên máy chủ để trình duyệt kiểm tra các tiêu đề được trả lại. Đây chính là lý do tại sao yêu cầu của bạn thực thi trên máy chủ.

Bạn có thể xem Priciples of the Same-Origin Policy by A. Barth.

1

Xem bobince's answer tại một câu hỏi tương tự:

Theo mức XMLHttpRequest 2, trình duyệt cho phép chéo gốc GET là gửi mà không preflighting, nhưng tôi không cho phép các kết quả để được đọc từ phản ứng trừ khi miền từ xa được chọn tham gia. Không có thêm lỗ hổng nào tại đây vì bạn có thể đã gửi GET đến một URL tùy ý để gửi (bao gồm chuỗi truy vấn, cho giá trị đó) thông qua nhiều giao diện cơ bản khác.

Ví dụ: bạn luôn có thể tạo phần tử với src được đặt thành địa chỉ trên miền từ xa; lấy đi rằng khả năng tên miền chéo sẽ phá vỡ rất nhiều trang web hiện có.

liên quan:

Các vấn đề liên quan