У меня есть приложение vueJS, в котором есть iFrame, куда я загружаю контент. И родительское окно, и содержимое фрейма мои.
Если я перехожу на родительскую страницу в браузере вручную, iFrame покажет, что document.referrer
пусто. Если я затем перефразирую sh, то родительская страница document.referrer
будет корректным родительским URL-адресом в iFrame.
Есть ли условие гонки при воспроизведении?
MVP для родительской страницы
<template>
<div>
<iframe
id="frame1"
name="frame1"
:src="getFrame1Src" />
<iframe
id="frame2"
name="frame2"
:src="getFrame2Src" />
</div>
</template>
<script>
export default {
name: 'parent',
data: () => ({
frame1Src: 'https://example1.com/path1',
frame2Src: 'https://example2.com/path2',
frame1Done: false,
frame2Done: false,
}),
computed: {
getFrame1Src() { return this.frame1Src },
getFrame2Src() { return this.frame2Src },
},
mounted() {
window.addEventListener('message', this.iFrameMessageHandler)
setInterval(this.messageJumper, 1000)
this.loadIFrames()
},
methods: {
messageJumper() {
if (!this.frame1Done || !this.frame2Done) return
this.$emit('Done')
},
iFrameMessageHandler(event) {
console.log('parent-received-event', event)
if (event.data === 'Done1') this.frame1Done = true
else if (event.data === 'Done2') this.frame2Done = true
// ? Other messages will pass through this handler too
},
loadIFrames() {
const someData1 = 'Data 1'
const someData2 = 'Data 2'
//! Closure is a bitch.. And apparently doesn't work as exptected
const frame1 = document.getElementById('frame1')
frame1.addEventListener('load', () => {
frame1.contentWindow.postMessage({ from: 'parent', someData: someData1 }, this.frame1Src.split('/').slice(0, -1).join('/'))
})
const frame2 = document.getElementById('frame2')
frame2.addEventListener('load', () => {
frame2.contentWindow.postMessage({ from: 'parent', someData: someData2 }, this.frame2Src.split('/').slice(0, -1).join('/'))
})
},
}
}
</script>
MVP для iFrame
<template>
<div>
</div>
</template>
<script>
export default {
name: 'frame1',
data: () => ({
whoAmI: 'frame1',
parentOrigin: '',
}),
mounted() {
this.parentOrigin = document.referrer.split('/')[2]
console.log('parentOrigin', this.parentOrigin)
window.addEventListener('message', this.parentMessageHandler)
this.messageTestIFrame()
},
methods: {
parentMessageHandler(event) {
if (event.origin.split('/')[2] === this.parentOrigin) {
//? parent is not a security test, it's a "what message is this validation"
if (event.data && typeof event.data === 'object' && event.data.from === 'parent' && event.data.someData) {
// Do something with the message
console.log(`${this.whoAmI}-received-event`, event)
}
}
},
messageTestIFrame() {
if (this.parentOrigin === 'example.com')
window.parent.postMessage(this.whoAmI, `https://${this.parentOrigin}`)
else if (this.parentOrigin.includes('localhost'))
window.parent.postMessage(this.whoAmI, `http://${this.parentOrigin}`)
else
console.log(`${this.whoAmI}: Bad parent origin [${this.parentOrigin}]`)
},
}
}
</script>