جاوااسکریپت - چگونه بین iframe و سایت والد ارتباط برقرار کنیم؟


وبسایتی که در iframe قرار دارد در همان دامنه نیست، اما هر دو متعلق به من هستند و من میخواهم بین iframe و سایت والد ارتباط برقرار کنم. آیا این امکانپذیر است؟

پاسخ شماره ۱

با دامنههای مختلف، امکان فراخوانی متدها یا دسترسی مستقیم به سند محتوای iframe وجود ندارد.

شما باید از پیامرسانی بین اسناد استفاده کنید.

والد -> فریمصفحه

برای مثال در پنجره بالایی:

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

و در آیفریم:

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

iframe -> والد

به عنوان مثال در پنجره بالایی:

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

و در آیفریم:

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

پاسخ شماره ۲

در سال ۲۰۱۸ و مرورگرهای مدرن، شما میتوانید یک رویداد سفارشی از iframe به پنجره والد ارسال کنید.

ایفریم :

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

والد :

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

پینوشت: البته، شما میتوانید رویدادها را به همان روش در جهت مخالف ارسال کنید.

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

پاسخ شماره ۳

این کتابخانه از HTML5 postMessage و مرورگرهای قدیمی با resize+hash پشتیبانی میکند https://github.com/ternarylabs/porthole

ویرایش: حالا در سال ۲۰۱۴، استفاده از IE6/7 بسیار کم است، IE8 و بالاتر همه postMessage را پشتیبانی میکنند، بنابراین اکنون پیشنهاد میکنم که فقط از آن استفاده کنید.

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

پاسخ شماره ۴

از event.source.window.postMessage برای ارسال مجدد به فرستنده استفاده کنید.

از آیفریم

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

سپس از والدین بگو بازگشت.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}

بهروزرسانی شد :

تابع postMessage نباید در دامنههای متقابل کار کند، بنابراین راهحل مانند این است:

به عنوان مثال وبسایت شما: customer.com و دامنه شما my.com است

تو باید اینطور انجام بدهی

  • یک فایل js ایجاد کنید (آن را در CDN یا سرور خود آپلود کنید) - my.com
  • فایل js بالا را در customer.com وارد کنید

حالا از my.com، شما میتوانید postMessage کنید و اسکریپت جاسازی شده بالاتر میتواند دادهها را از شما دریافت کند.