Làm thế nào để giao tiếp giữa iframe và trang mẹ?


183

Trang web trong iframe không nằm trong cùng một tên miền , nhưng cả hai đều là của tôi và tôi muốn liên lạc giữa iframetrang web chính và trang mẹ. Có thể không?

Câu trả lời:


303

Với các miền khác nhau, không thể gọi phương thức hoặc truy cập trực tiếp vào tài liệu nội dung của iframe.

Bạn phải sử dụng tin nhắn tài liệu chéo .

Ví dụ trong cửa sổ trên cùng:

 myIframe.contentWindow.postMessage('hello', '*');

và trong iframe:

window.onmessage = function(e){
    if (e.data == 'hello') {
        alert('It works!');
    }
};

Nếu bạn đang đăng thông báo từ iframe lên cửa sổ cha

window.top.postMessage('hello', '*')

2
cảm ơn bạn, nhưng thật không may, nó không hoạt động trong các trình duyệt cũ hơn.
Danny Fox

106
Trong cha mẹ : window.onmesage = function().... Trong iframe:window.top.postMessage('hello', '*')
user123444555621

3
Đó không phải là một lỗi. Các url tệp có thể rất không an toàn và các trình duyệt đang xử lý chúng với sự chăm sóc ngày càng tăng. Quay lại những ngày xưa, bạn có thể đặt một liên kết đến file://C:/Windows/system32/whatevermột trang web và làm cho nó trỏ thẳng vào thư mục hệ thống của người dùng. Ngày nay các trình duyệt chủ yếu bỏ qua các nhấp chuột vào các liên kết như thế. Chạy một máy chủ web và truy cập mã của bạn thông qua đó và bạn sẽ thấy các lỗi diappear.
Stijn de Witt

4
Là một cách thực hành tốt, không bao giờ sử dụng '*' cho mục tiêu của bạn. Trên thực tế, MDN nói - "Luôn cung cấp một mục tiêu cụ thể, không phải *, nếu bạn biết vị trí của tài liệu của cửa sổ khác. Không cung cấp mục tiêu cụ thể tiết lộ dữ liệu bạn gửi đến bất kỳ trang web độc hại nào quan tâm."
Rodiwa

2
Chúng ta thậm chí có thể sử dụng window.frames[index]để lấy khung con ( <iframe>, <object>, <frame>), tương đương với getElementsByTagName("iframe")[index].contentWindow. Để có được Đối tượng cửa sổ phụ huynh từ IFrames, tốt hơn là sử dụng window.parent, như window.topđại diện cho Cửa sổ phụ huynh nhiều nhất
Subroto

44

Nó phải ở đây, vì câu trả lời được chấp nhận từ năm 2012

Trong năm 2018 và các trình duyệt hiện đại, bạn có thể gửi một sự kiện tùy chỉnh từ iframe đến cửa sổ cha.

iframe:

var data = { foo: 'bar' }
var event = new CustomEvent('myCustomEvent', { detail: data })
window.parent.document.dispatchEvent(event)

cha mẹ:

window.document.addEventListener('myCustomEvent', handleEvent, false)
function handleEvent(e) {
  console.log(e.detail) // outputs: {foo: 'bar'}
}

PS: Tất nhiên, bạn có thể gửi các sự kiện theo hướng ngược lại theo cùng một cách.

document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)

1
Xin chào, tôi có phải ở trên cùng một tên miền để làm điều đó không?
Guillaume Harari


1
Cần lưu ý rằng dispatchEventđược hỗ trợ trong tất cả các trình duyệt chính. IE9 là phiên bản đầu tiên mà nó xuất hiện, vì vậy hầu hết các hệ điều hành hiện nay đều hoạt động với nó. caniuse.com/#search=dispatchEvent
Dan Atkinson

1
Tôi không thể giao tiếp từ cha mẹ đến iframe bằng phương pháp này.
Avan

Vâng, tôi cũng không thể làm cho nó hoạt động được, iframe js đang tải sau cửa sổ cha mẹ để nó không ở đó để nhận thông điệp khi được gửi. nó chỉ hoạt động từ iframe đến cha mẹ cho tôi.
radtek

14

Thư viện này hỗ trợ HTML5 postMessage và các trình duyệt cũ với thay đổi kích thước + băm https://github.com/ternarylabs/porthole

Chỉnh sửa: Bây giờ trong năm 2014, việc sử dụng IE6 / 7 khá thấp, IE8 và trên hết là hỗ trợ postMessagenên giờ tôi đề nghị chỉ sử dụng nó.

https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage


Với lời cảnh báo rằng IE8 / 9 chỉ hỗ trợ các chuỗi caniuse.com/#search=postmessage (Xem các vấn đề đã biết)
Harry

điều này có thể được giải quyết bằng cách mã hóa các đối tượng sự kiện của bạn thành json và giải mã chúng ở phía bên kia.
viết mã



1

Sử dụng event.source.window.postMessageđể gửi lại cho người gửi.

Từ khung nội tuyến

window.top.postMessage('I am Iframe', '*')
window.onmessage = (event) => {
    if (event.data === 'GOT_YOU_IFRAME') {
        console.log('Parent received successfully.')
    }
}

Rồi từ bố mẹ nói lại.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
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.