Làm cách nào để bạn sử dụng window.postMessage trên các miền?


89

Có vẻ như quan điểm của window.postMessage là cho phép giao tiếp an toàn giữa các cửa sổ / khung được lưu trữ trên các miền khác nhau, nhưng nó thực sự không cho phép điều đó trong Chrome.

Đây là tình huống:

  1. Nhúng <iframe> (với srctên miền B * ) vào một trang trên tên miền A
  2. <iframe> kết thúc phần lớn là một thẻ <script>, ở phần cuối của việc thực thi ...
  3. Tôi gọi window.postMessage ( some_data , page_on_A )

<iframe> chắc chắn nhất trong ngữ cảnh của miền B và tôi đã xác nhận rằng javascript nhúng trong <iframe> đó thực thi đúng cách và gọi postMessagevới các giá trị chính xác.

Tôi nhận được thông báo lỗi này trong Chrome:

Không thể gửi thông điệp tới Một . Người nhận có nguồn gốc B .

Đây là mã đăng ký trình xử lý sự kiện thông báo trong trang trên A:

window.addEventListener(
  "message",
  function (event) {
    // Do something
  },
  false);

Tôi cũng đã thử gọi window.postMessage(some_data, '*'), nhưng tất cả những gì làm được là không xảy ra lỗi.

Tôi chỉ thiếu điểm ở đây, có phải window.postMessage (...) không dành cho điều này? Hay tôi chỉ làm sai một cách khủng khiếp?

* Văn bản / html kiểu mime, mà nó phải được giữ nguyên.


1
Có thể bạn đã biết về điều này, nhưng MDC có một bản tóm tắt tuyệt vời trên postMessage: developer.mozilla.org/en/DOM/window.postMessage Đối với việc triển khai FF rõ ràng, nhưng có thể có điều gì đó giải thích tại sao nó không hoạt động.
Pekka

Câu trả lời:


79

Đây là một ví dụ hoạt động trên Chrome 5.0.375.125.

Trang B (nội dung iframe):

<html>
    <head></head>
    <body>
        <script>
            top.postMessage('hello', 'A');
        </script>
    </body>
</html>

Lưu ý việc sử dụng top.postMessagehay parent.postMessagekhông window.postMessagetại đây

Trang A:

<html>
<head></head>
<body>
    <iframe src="B"></iframe>
    <script>
        window.addEventListener( "message",
          function (e) {
                if(e.origin !== 'B'){ return; } 
                alert(e.data);
          },
          false);
    </script>
</body>
</html>

A và B phải là một cái gì đó giống như http://domain.com

BIÊN TẬP:

Từ một câu hỏi khác , có vẻ các lĩnh vực (A và B ở đây) phải có /cho postMessagehoạt động tốt.


3
Khi trang A kiểm tra nguồn gốc của thư, nguồn gốc sẽ KHÔNG chứa dấu '/'. Dường như không quan trọng nếu trang B có chỉ định dấu '/' hay không. Điều khác cần lưu ý là URL phải là URL tuyệt đối.
Bắt 22

1
Câu trả lời này khiến tôi hơi bối rối và vẫn đang tìm kiếm câu trả lời. blog.teamtreehouse.com/cross-domain-messaging-with-postmessage có giải thích rất hay về postMessage. Điều quan trọng là người gửi tin nhắn biết miền của người nhận. Trong ví dụ trên, A và B không phải là lĩnh vực tương tự, nhưng B phải biết chính xác những gì miền được sử dụng bởi A.
Greg Bogumił

7
Câu hỏi là về miền chéo. Câu trả lời được chấp nhận là về cùng một miền.
stackular

@stackular, không chính xác. A và B có thể là miền bất kỳ. Đó là lý do chính của việc cópostMessage
Mic

1
+1. Chúng tôi muốn xác nhận rằng giải pháp này đã hoạt động trên trường hợp của chúng tôi. Chúng tôi có một trang chứa iframe từ miền khác . Xin lưu ý rằng điều này chỉ hoạt động trong trình duyệt Chrome, vì trong firefox, chúng tôi cần sử dụng window.parent.postMessage thay vì top . Mặc dù chúng tôi không biết liệu điều này có thể được áp dụng cho bất kỳ trình duyệt nào khác hay không.
rahmatns

24

Bạn nên gửi một tin nhắn từ khung cho phụ huynh, sau khi tải.

kịch bản khung:

$(document).ready(function() {
    window.parent.postMessage("I'm loaded", "*");
});

Và lắng nghe nó trong cha mẹ:

function listenMessage(msg) {
    alert(msg);
}

if (window.addEventListener) {
    window.addEventListener("message", listenMessage, false);
} else {
    window.attachEvent("onmessage", listenMessage);
}

Sử dụng liên kết này để biết thêm thông tin: http://en.wikipedia.org/wiki/Web_Messaging


2

Có thể bạn cố gắng gửi dữ liệu của mình từ mydomain.com đến www.mydomain.com hoặc ngược lại, LƯU Ý bạn đã bỏ lỡ "www". http://mydomain.comhttp://www.mydomain.com là các tên miền khác nhau đối với javascript.


2
Trong một dự án tôi đang thực hiện, tôi đang sử dụng file:/// Có thể gặp lỗi miền khi chỉ kéo nội dung từ hệ thống tệp cục bộ không?
Jacksonkr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.