I'm working inside a Nuxt JS 2 project and have a global injected function called createIcicleIframeBridge and purgeIcicleHashBetweenDomains. These functions are part of a plugin, and are called from within the mounted hook of a page.
When I call the purge function, it complains and says:
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://icicle.ext') does not match the recipient window's origin ('http://127.0.0.1:8001')
If I wrap the postMessage in a timeout of a few seconds, then it works as intended and the error goes. I've wrote another global function that'll keep checking if the element exists before attempting to post a message to the iframe, which works in terms of delaying and continuously checking for X seconds, but when combined with my purge check, the javascript still seems to think the iFrame doesn't exist.
I don't want to rely on a setTimeout with a single defined value as this will cause reliability issues.
My plugin file:
/*
** Post Icicle bridge data
*/
function postIcicleBridgeData (app, data, url = 'https://icicle.ext') {
app.$waitForGlobalElement('[data-icicle-hash-bridge]', () => {
const bridge = document.querySelector('[data-icicle-hash-bridge]').contentWindow
if (bridge) bridge.postMessage(data, url)
})
}
export default function ({ app, route, redirect, context }, inject) {
/*
** Create a bridge to Icicle for cross-domain
*/
inject('createIcicleIframeBridge', (url = 'https://icicle.ext') => {
setTimeout(() => {
const iframeBridge = document.createElement('iframe')
iframeBridge.src = `${url}?v=${Math.round(new Date().getTime() / 1000)}`
iframeBridge.dataset.icicleHashBridge = true
iframeBridge.style.display = 'none'
document.getElementsByTagName('BODY')[0].appendChild(iframeBridge)
}, 3 * 1000)
})
/*
** Clear global hash
*/
inject('purgeIcicleHashBetweenDomains', () => {
postIcicleBridgeData(app, 'purgeHash')
})
/*
** Wait for global element to become available
*/
inject('waitForGlobalElement', (key, callback, delay = 10) => {
if (document.querySelector(key)) {
callback()
} else {
setTimeout(() => {
app.$waitForGlobalElement(key, callback)
}, delay)
}
})
}
Then called from within a page:
mounted () {
this.$createIcicleIframeBridge()
// clear Icicle hash in case customer doesn't apply
this.$purgeIcicleHashBetweenDomains()
}
What am I missing here? What do I need to change so that I can ensure whenever my purge function runs the iFrame is always there.