2009-08-18 29 views
16

Tôi kiểm soát nội dung của iframe được nhúng trong một trang từ một tên miền khác. Có cách nào để javascript trong iframe của tôi thực hiện thay đổi đối với DOM của cha mẹ không?<iframe> javascript truy cập vào DOM mẹ trên các tên miền?

Ví dụ: tôi muốn có tập lệnh iframe thêm một loạt các phần tử html vào DOM mẹ. Điều này có vẻ như một thứ tự khá cao - suy nghĩ?

Chỉnh sửa: Có một kỹ thuật được gọi là "Fragment ID Messaging", đây có thể là cách để giao tiếp giữa iframe nhiều miền.

Chỉnh sửa: Ngoài ra, Firefox 3.5, Opera, Chrome (v.v) dường như đang sử dụng html5 "postMessage" api, cho phép truyền dữ liệu giữa nhiều miền, an toàn giữa các khung, iframe và cửa sổ bật lên. Nó hoạt động giống như một hệ thống sự kiện. IE8 hỗ trợ tính năng này, rõ ràng, có lẽ là một chút đáng ngạc nhiên.

Tóm tắt: Không, bạn không thể trực tiếp truy cập/chỉnh sửa DOM của trang từ tên miền khác. Nhưng bạn có thể giao tiếp với nó và nó có thể hợp tác để thực hiện các thay đổi bạn muốn.

+0

Câu trả lời hiện được chấp nhận là chính xác trong năm 2009, nhưng thời gian đã thay đổi. Stefan Steiger là tốt hơn và nó có thể là giá trị thay đổi câu trả lời chấp nhận của bạn với nó. – Quentin

+0

Cảm ơn @Quentin, tôi sẽ cân nhắc điều này. – aaaidan

Trả lời

17

Ghét để nói điều đó nhưng tôi chắc chắn rằng 99% chắc chắn không xảy ra trực tiếp do bảo mật.

Bạn có thể dùng thử here.

bhh

+1

Cảm ơn, liên kết đó thể hiện vấn đề rất tốt. – aaaidan

+12

PS. Bạn đã hủy hoại ngày của tôi, nhưng cảm ơn. : P – aaaidan

+3

hey người đàn ông, đó là những gì tôi làm;) –

0

Tôi đoán bạn sẽ gặp phải sự cố bảo mật mà không cần sử dụng proxy. Proxy có thể rất dễ sử dụng. Bạn có thể thử một trong những:

(1) một PHP based proxy (có nguyên nhân cẩn thận có rất nhiều quảng cáo giữa các liên kết hữu ích)

(2) proxy Apache .htaccess - chỉ cần tạo một thư mục con proxy tại của bạn miền và đặt ở đó một tập tin .htaccess chứa:

RewriteEngine on 
RewriteRule ^(.*)$ http://picasaweb.google.com/$1 [P,L] 

đặt tên miền khác ở vị trí của picasaweb.google.com

Cá nhân tôi thích sử dụng proxy Apache

+0

Cảm ơn câu trả lời của bạn, warpech. Tôi nghĩ rằng các chỉnh sửa của tôi đã nhầm lẫn câu hỏi ban đầu của tôi mặc dù, đó là yêu cầu làm thế nào tôi có thể thay đổi các dom trên một trang cha mẹ từ bên trong một khung nội tuyến từ một tên miền khác. Câu trả lời ngắn có vẻ là "bạn không thể". Vì vậy, bây giờ tôi đang khám phá các phương thức giao tiếp giữa các khung, và một proxy phía máy chủ chắc chắn là một trong số đó. Cảm ơn! – aaaidan

11

Có thể.

Bạn có quyền đề cập đến postMessage trong các chỉnh sửa của mình. Đối với những người đang tìm kiếm, có một cách tương thích ngược, chỉ có javascript để giao tiếp giữa các tên miền. Ngắn, dễ dàng mã là tốt. Giải pháp hoàn hảo? Chừng nào bạn có thể yêu cầu sửa đổi các phụ huynh và trẻ em:

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

+0

nó hoạt động như một sự quyến rũ. cảm ơn rất nhiều –

0

Đối với AJAX, máy chủ có thể trở lại tiêu đề Access-Control-Allow-Origin: * cho phép truy cập cross-domain. Có lẽ nó cũng hoạt động cho IFRAME.

+1

không, nó không. Tôi chỉ cố gắng. – Leonardo

5

Có thể.
Bạn có thể triển khai window.postMessage để giao tiếp qua iframe và/hoặc cửa sổ trên các tên miền.
Nhưng bạn cần thực hiện nó theo cách không đồng bộ.
Nếu bạn cần đồng bộ, bạn cần triển khai trình bao bọc xung quanh các phương pháp không đồng bộ đó.

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
    <title></title> 

    <!-- 
    <link rel="shortcut icon" href="/favicon.ico"> 


    <link rel="start" href="http://benalman.com/" title="Home"> 

    <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css"> 

    <script type="text/javascript" src="/js/mt.js"></script> 
    --> 
    <script type="text/javascript"> 
     // What browsers support the window.postMessage call now? 
     // IE8 does not allow postMessage across windows/tabs 
     // FF3+, IE8+, Chrome, Safari(5?), Opera10+ 

     function SendMessage() 
     { 
      var win = document.getElementById("ifrmChild").contentWindow; 

      // http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/ 


      // http://stackoverflow.com/questions/16072902/dom-exception-12-for-window-postmessage 
      // Specify origin. Should be a domain or a wildcard "*" 

      if (win == null || !window['postMessage']) 
       alert("oh crap"); 
      else 
       win.postMessage("hello", "*"); 
      //alert("lol"); 
     } 



     function ReceiveMessage(evt) { 
      var message; 
      //if (evt.origin !== "http://robertnyman.com") 
      if (false) { 
       message = 'You ("' + evt.origin + '") are not worthy'; 
      } 
      else { 
       message = 'I got "' + evt.data + '" from "' + evt.origin + '"'; 
      } 

      var ta = document.getElementById("taRecvMessage"); 
      if (ta == null) 
       alert(message); 
      else 
       document.getElementById("taRecvMessage").innerHTML = message; 

      //evt.source.postMessage("thanks, got it ;)", event.origin); 
     } // End Function ReceiveMessage 




     if (!window['postMessage']) 
      alert("oh crap"); 
     else { 
      if (window.addEventListener) { 
       //alert("standards-compliant"); 
       // For standards-compliant web browsers (ie9+) 
       window.addEventListener("message", ReceiveMessage, false); 
      } 
      else { 
       //alert("not standards-compliant (ie8)"); 
       window.attachEvent("onmessage", ReceiveMessage); 
      } 
     } 
    </script> 


</head> 
<body> 

    <iframe id="ifrmChild" src="child.htm" frameborder="0" width="500" height="200" ></iframe> 
    <br /> 


    <input type="button" value="Test" onclick="SendMessage();" /> 

</body> 
</html> 

Child.htm

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
    <title></title> 

    <!-- 
    <link rel="shortcut icon" href="/favicon.ico"> 


    <link rel="start" href="http://benalman.com/" title="Home"> 

    <link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css"> 

    <script type="text/javascript" src="/js/mt.js"></script> 
    --> 

    <script type="text/javascript"> 
     /* 
     // Opera 9 supports document.postMessage() 
     // document is wrong 
     window.addEventListener("message", function (e) { 
      //document.getElementById("test").textContent = ; 
      alert(
       e.domain + " said: " + e.data 
       ); 
     }, false); 
     */ 

     // https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage 
     // http://ejohn.org/blog/cross-window-messaging/ 
     // http://benalman.com/projects/jquery-postmessage-plugin/ 
     // http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html 

     // .data – A string holding the message passed from the other window. 
     // .domain (origin?) – The domain name of the window that sent the message. 
     // .uri – The full URI for the window that sent the message. 
     // .source – A reference to the window object of the window that sent the message. 
     function ReceiveMessage(evt) { 
      var message; 
      //if (evt.origin !== "http://robertnyman.com") 
      if(false) 
      { 
       message = 'You ("' + evt.origin + '") are not worthy'; 
      } 
      else 
      { 
       message = 'I got "' + evt.data + '" from "' + evt.origin + '"'; 
      } 

      //alert(evt.source.location.href) 

      var ta = document.getElementById("taRecvMessage"); 
      if(ta == null) 
       alert(message); 
      else 
       document.getElementById("taRecvMessage").innerHTML = message; 

      // http://javascript.info/tutorial/cross-window-messaging-with-postmessage 
      //evt.source.postMessage("thanks, got it", evt.origin); 
      evt.source.postMessage("thanks, got it", "*"); 
     } // End Function ReceiveMessage 




     if (!window['postMessage']) 
      alert("oh crap"); 
     else { 
      if (window.addEventListener) { 
       //alert("standards-compliant"); 
       // For standards-compliant web browsers (ie9+) 
       window.addEventListener("message", ReceiveMessage, false); 
      } 
      else { 
       //alert("not standards-compliant (ie8)"); 
       window.attachEvent("onmessage", ReceiveMessage); 
      } 
     } 
    </script> 


</head> 
<body style="background-color: gray;"> 
    <h1>Test</h1> 

    <textarea id="taRecvMessage" rows="20" cols="20" ></textarea> 

</body> 
</html> 

Ở đây, bạn sẽ sửa đổi các con để gửi postmessages để cha mẹ. ví dụ: trong child.htm, bạn làm

window.parent.postMessage("alert(document.location.href); document.location.href = 'http://www.google.com/ncr'", "*"); 

và phụ huynh, bạn làm (trong receiveMessage) Không phải là sử dụng eval là không an toàn, do đó bạn sẽ thay vượt qua một enum, và gọi hàm tương ứng mà bạn cần phải đặt trên trang gốc.

+0

Việc tải khung nội tuyến con sẽ không hoạt động trong môi trường chế độ hỗn hợp. Ví dụ: trang chính trong https và trang con trong iframe (http). – lmiguelmh

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