document.referrer пуст в iframe (работает с refre sh) - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть приложение 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>
...