2009-03-16 41 views
44

Giả sử tôi có trang chính được tải từ http://www.example.com/index.html. Trên trang đó có mã js tạo yêu cầu ajax thành http://n1.example.com//echo?message=hello. Khi phản hồi được nhận một div trên trang chính được cập nhật với phần thân phản hồi.Câu hỏi về yêu cầu ajax tên miền chéo (tên miền phụ)

Điều đó có hoạt động trên tất cả các trình duyệt phổ biến không?

Edit:

Các giải pháp rõ ràng là đặt một proxy trước www.example.com và n1.example.com và thiết lập nó để mọi yêu cầu đi đến một subresource của http://www.example.com/n1 được proxy để http://n1.example.com/.

+0

Có thể là không. Đây là hai tên miền khác nhau nên yêu cầu miền chéo do đó bị chặn bởi trình duyệt. –

Trả lời

17

Một giải pháp khác có thể hoặc có thể không hiệu quả đối với bạn là chèn/xóa thẻ tập lệnh trong DOM của bạn trỏ đến tên miền đích. Điều này sẽ làm việc nếu mục tiêu trả về json và hỗ trợ gọi lại.

Chức năng để xử lý các kết quả:

<script type="text/javascript"> 
    function foo(result) { 
    alert(result); 
    } 
</script> 

Thay vì làm một yêu cầu AJAX bạn sẽ tự động chèn một cái gì đó như thế này:

<script type="text/javascript" src="http://n1.example.com/echo?callback=foo"></script> 
+0

thats một cách thú vị để đi về nó ...cool – johnnietheblack

+12

Kỹ thuật này được gọi là JSONP. Các khung công tác JavaScript chính có khả năng này trong các thư viện AJAX của họ. – yfeldblum

+0

Giải pháp tuyệt vời! –

1

workaround khác, là để chỉ đạo theo yêu cầu ajax đến một php (ví dụ) trang trên tên miền của bạn và trong trang đó tạo yêu cầu cURL cho tên miền phụ.

133

Tên miền chéo hoàn toàn là một chủ đề khác. Nhưng qua tiểu tên miền là tương đối dễ dàng. Tất cả những gì bạn cần làm là đặt document.domain thành giống nhau trong cả trang gốc và trang iframe.

document.domain = "yourdomain.com" 

More info here

Lưu ý: kỹ thuật này will only let you interact with iframes from parents of your domain. Nó làm không thay đổi Nguồn gốc được gửi bởi XMLHttpRequest.

+10

Một câu trả lời "đúng" khác đã được chọn không đúng. Đây là câu trả lời đúng cho câu hỏi. Các miền chia sẻ tên miền cấp hai (với một số ngoại lệ nhỏ) luôn có thể đặt tên miền của mình để cho phép truy cập rộng hơn trong số các miền khác chia sẻ tên miền phụ. – Jordan

+4

Không phải lo lắng, nó vẫn được bình chọn cao nhất và dễ tìm. stackoverflow là rất tốt. – zod

+11

Có lẽ tôi đang bối rối nhưng ông không đề cập đến bất cứ điều gì về một khung nội tuyến. Điều đó có ảnh hưởng đến hiệu lực của câu trả lời không? Nói cách khác, bạn có thể sử dụng phương pháp này khi không có iframe và có lẽ chúng ta đang nói về một tên miền phụ đang được sử dụng như là một api RESTful? (Cross browser) –

1

Ý tưởng mới: nếu bạn muốn qua tên miền phụ (www.domain.com và sub.domain.com) và bạn đang làm việc trên apache. mọi thứ có thể dễ dàng hơn nhiều. nếu một tên miền phụ thực sự là một thư mục con trong public_html (sub.domain.com = www.domain.com/sub/. vì vậy nếu bạn có ajax.domain.com/?request=subject ... bạn có thể làm một cái gì đó như thế này: www yêu cầu = đối tượng

công trình như một say mê đối với tôi, và không có hacks ngu ngốc, proxy hoặc những điều khó khăn để làm cho chỉ một vài yêu cầu Ajax!

1

Giải pháp đơn giản nhất mà tôi tìm thấy là tạo một php trên tên miền phụ của bạn và bao gồm tệp chức năng ban đầu của bạn bên trong nó bằng cách sử dụng đường dẫn đầy đủ.

Ví dụ:

www.domain.com/ajax/this_is_where_the_php_is_called.php

Subdomain:

sub.domain.com

Tạo: sub.domain.com/I_need_the_function.php

Bên I_need_the_function.php chỉ cần sử dụng bao gồm:

include_once ("/ server/path/public_html/ajax/this_is_where_the_php_is_called.php");

Bây giờ gọi sub.domain.com/I_need_the_function.php từ javascript của bạn.

var sub=""; 
switch(window.location.hostname) 
{ 
case "www.domain.com": 
sub = "/ajax/this_is_where_the_php_is_called.php"; 
break; 
case "domain.com": 
sub = ""; 
break; 
default: ///your subdomain (or add more "case" 's) 
sub = "/I_need_the_function.php"; 
} 


xmlHttp.open("GET",sub,true); 

Ví dụ đơn giản như tôi có thể làm. Bạn có thể muốn sử dụng đường dẫn được định dạng tốt hơn.

Tôi hy vọng điều này sẽ giúp ích cho bạn. Không có gì lộn xộn ở đây - và bạn đang gọi tệp gốc, vì vậy mọi chỉnh sửa sẽ áp dụng cho tất cả các chức năng.

15

Tất cả các trình duyệt hiện đại đều hỗ trợ CORS và từ đó chúng tôi nên tận dụng bổ sung này.

Nó hoạt động trên kỹ thuật bắt tay đơn giản là 2 miền truyền thông tin tưởng lẫn nhau bằng cách gửi tiêu đề HTTP/nhận được. Điều này đã được chờ đợi từ lâu vì chính sách gốc giống nhau là cần thiết để tránh XSS và các nỗ lực độc hại khác.

Để bắt đầu yêu cầu nguồn gốc, trình duyệt sẽ gửi yêu cầu với tiêu đề HTTP gốc. Giá trị của tiêu đề này là trang phục vụ trang. Ví dụ: giả sử một trang trên http://www.example-social-network.com nỗ lực truy cập vào dữ liệu của người dùng trong online-personal-calendar.com. Nếu trình duyệt của người dùng thực hiện CORS, tiêu đề yêu cầu sau đây sẽ được gửi:

Xuất xứ: http://www.example-social-network.com

Nếu online-personal-calendar.com phép theo yêu cầu, nó sẽ gửi một tiêu đề Access-Control-Allow-Origin trong phản ứng của nó. Giá trị của tiêu đề cho biết các trang web gốc nào được cho phép. Ví dụ, một phản ứng với yêu cầu trước đó sẽ chứa những điều sau đây:

Access-Control-Allow-Origin: http://www.example-social-network.com

Nếu máy chủ không cho phép yêu cầu cross-nguồn gốc, trình duyệt sẽ cung cấp một lỗi trang example-social-network.com thay vì trả lời trực tuyến-personal-calendar.com.

Để cho phép truy cập vào tất cả các trang, một máy chủ có thể gửi đáp ứng tiêu đề sau đây:

Access-Control-Allow-Origin: *

Tuy nhiên, điều này có thể không thích hợp cho các tình huống trong đó an ninh là một mối quan tâm.

Rất được giải thích ở đây dưới trang wiki. http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

+1

Tóm tắt tuyệt vời! – mbfisher

+3

IE 8 & 9 không hỗ trợ đầy đủ CORS. Ít nhất là cho các trang web của tôi, đây vẫn là một phần đáng kể lưu lượng truy cập. – Brad

+0

Tôi đoán nó hoạt động cho IE9, có thể là tôi sai vì tôi đã sử dụng jQuery CORS plugin để thêm hỗ trợ cho IE8 +. https://gist.github.com/mathieucarbou/1114981 –

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