2009-08-18 39 views
9

Trong quá trình tìm hiểu các yêu cầu Ajax bằng cách sử dụng jQuery, tôi đã cố gắng tải trang chủ của google vào một liên kết. Vì vậy, tôi đã viết một cái gì đó như:Tại sao tôi không thể tải một tài nguyên bên ngoài từ phương thức tải jQuery?

$("#ajax").click (function (event) { 
    $("#g").html("Loading..."); 
    $("#g").load("http://www.google.com"); 
    event.preventDefault(); 
}); 

Và nơi nào đó trong cơ thể:

<a id="ajax" href="http://www.google.com">Load file ajax way</a> 
<div id="g">Click the above link to load the page...</div> 

nào không làm việc và bước đầu tôi nghĩ có một số lỗi cú pháp hoặc một cái gì đó. Nhưng sau này khi tôi thay thế url google bằng một tệp html tĩnh trên máy chủ, nó hoạt động chính xác.

$("#g").load("Temp.htm"); 

Được thiết kế để hoạt động như thế này (nếu có, tại sao?) Hoặc tôi đang làm điều gì đó sai?

EDIT: Vui lòng bất cứ ai có thể giải thích (hoặc tham khảo) vấn đề bảo mật được giới thiệu bởi các cuộc gọi ajax giữa tên miền? Nói cách khác, tại sao an toàn để mở một tab trình duyệt khác và mở google nhưng KHÔNG phải từ bên trong trang? Là nó để bảo vệ người gọi hoặc callee?

Trả lời

34

Jquery sử dụng yêu cầu ajax (XMLHttpRequest) để tải dữ liệu, nhưng trình duyệt cho phép điều này cho các tài nguyên trên cùng một tên miền. (Các câu trả lời ở trên đề cập đến Same origin policy). Đó là lý do tại sao nó hoạt động với Temp.htm, nhưng không hoạt động với www.google.com.

  • Một cách để giải quyết vấn đề này là tạo tập lệnh máy chủ sẽ tải trang cho bạn - về cơ bản là proxy. Sau đó, bạn gọi

    $('#g').load("load.php?url=google.com") 
    
  • Các giải pháp khác là sử dụng iframe để giao tiếp - Tôi tìm thấy thư viện này, đó có vẻ là những gì bạn cần: jquery-crossframe

  • Một lựa chọn thứ ba là JSONP nhưng điều đó sẽ không làm việc nó là trường hợp của bạn.

Ý kiến ​​của tôi - hãy chọn tùy chọn đầu tiên với proxy phía máy chủ.


Tại sao có chính sách gốc giống nhau?

Hãy tưởng tượng bạn đang kiểm tra một số nội dung trên tài khoản ebay của mình. Sau đó, trong một tab khác bạn mở trang web của tôi, nơi tôi có một kịch bản mà làm cho một loạt các yêu cầu để ebay (bạn vẫn còn đăng nhập) và chào giá bạn cho một chiếc Audi A8 mà bạn thậm chí không nhận thấy. Gây phiền nhiễu ... Nếu đó là ngân hàng của bạn, nó có thể lấy cắp tiền trực tiếp từ bạn.

Điều trớ trêu là mặc dù có cùng chính sách gốc, nhưng cuộc tấn công trên vẫn có thể xảy ra.

+3

+1 Câu trả lời tuyệt vời. –

+2

Câu trả lời rất toàn diện và đầy đủ –

+0

do đó load.php chỉ đọc miền được truy vấn và lưu trữ nội dung? – 3zzy

2

Bạn không được phép thực hiện cuộc gọi AJAX tên miền chéo vì lý do bảo mật - xem Same Origin Policy.

1

Điều này là do bảo mật. Bạn có thể đọc tất cả về nó cùng với một giải pháp trên tại yahoo.

0

Trước hết, tôi phải giả định rằng bạn có một lý do rất tốt để làm điều gì đó một liên kết không theo mặc định với JavaScript ...

Lý do chính có lẽ là an ninh: Bạn KHÔNG thể truy cập bất kỳ dữ liệu bên ngoài miền hiện tại từ JavaScript.

+0

Tôi KHÔNG có bất kỳ lý do gì để làm điều này. Tôi đã chỉ làm điều này cho việc học các cuộc gọi jQuery và Ajax (và ngây thơ đã cố gắng sử dụng google). Vì vậy, có lẽ tôi không bao giờ có thể cần phải gọi các máy chủ khác nhưng nó vẫn còn tốt để biết các giải pháp nếu nó là bao giờ cần thiết (đề xuất của Andy). – Hemant

1

Cần lưu ý rằng bạn không hoàn toàn bị loại trừ khỏi các yêu cầu tên miền chéo trong javascript.

Kể từ jQuery 1.2, bạn có thể tải dữ liệu JSON nằm trên một tên miền khác nếu bạn chỉ định một cuộc gọi lại JSON-P và URL mà bạn gọi hỗ trợ đầu ra JSON-P.

Ví dụ sau là trực tiếp từ tài liệu jQuery. Nó lấy bốn bức ảnh flickr cuối cùng được gắn thẻ "cat".

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", 
    function(data){ 
     $.each(data.items, function(i,item){ 
     $("<img/>").attr("src", item.media.m).appendTo("#images"); 
     if (i == 3) return false; 
     }); 
    }); 

Bạn có thể đọc các tài liệu ở đây: http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback

Cá nhân tôi sử dụng nó để kéo trong tweet mới nhất của tôi trên blog của tôi mà không cần phải xây dựng nó thành mã server-side của tôi. Điều đó cũng có lợi ích bổ sung là không phải viết mã xử lý lỗi cho dịch vụ API thường xuyên từ Twitter. Chỉ cần xem nguồn trên blog của tôi nếu bạn muốn nhìn thấy nó: http://joreteg.com

0

thử thêm

<IfModule mod_headers.c>Header add Access-Control-Allow-Origin: "http://yoursite.com/" 

trong htaccess.send một số thông số sử dụng

$("#g").load("http://www.google.com",{nomeaning:'nomeaning'}); 

này sẽ gửi một bài request.it làm việc cho tôi

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