Loading of iframes occurs only after receiving the content sent through the postMessage function

I have a scenario where an iframe is used to receive information through the contentWindow.postMessage function in order to log in to a page that I am creating. However, I am facing an issue where the page loads before the contentWindow.postMessage message is received. How can I ensure that the page loads only after the domain has received the necessary information?

Below is the code snippet:

Page containing the iframe:

<template>
    <iframe
        id="iframe" 
        name="iframe" 
        src="http://localhost:8081/login" 
        frameborder="0" style="overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;position:absolute;top:0px;left:0px;right:0px;bottom:0px" height="100%" width="100%"
        >
        ></iframe>
</template>

<script>
let show = true;
export default {
    
  name: 'appFrame',
    
    function(){ document.getElementById('iframe').contentWindow.postMessage({
      userData: { 
        info1: localStorage.info1,
        info2: localStorage.info2,
        info3: localStorage.info3
        }}, 
      'http://localhost:8081/list');
      },
  data () {
    return {
      //
    }
  }
}
</script>

<style scoped>

</style>

Here is the window.onmessage code snippet on the page where I want to load the information:

window.onmessage = function(event)
{
  if(event.origin == 'http://localhost:8080')
  
  document.getElementById('output').innerHTML = event.data;
  localStorage.setItem("info1", event.data.userData.info1);
  localStorage.setItem("info2", event.data.userData.info2);
  localStorage.setItem("info3", event.data.userData.info3);

  console.log("LOCALSTORAGE: ", localStorage.getItem("info1"), localStorage.getItem("info2"), localStorage.getItem("info3") )

};

What would be the best approach to address this issue?

Answer №1

Suppose your second application (accessible at http://localhost:8081) is a Vue.js application. The code you would need is as follows:

window.addEventListener('message', function(event) {
  if (event.origin == 'http://localhost:8080') {
    document.getElementById('output').innerHTML = event.data;
    localStorage.setItem("info1", event.data.userData.info1);
    localStorage.setItem("info2", event.data.userData.info2);
    localStorage.setItem("info3", event.data.userData.info3);

    console.log("LOCALSTORAGE: ", localStorage.getItem("info1"), localStorage.getItem("info2"), localStorage.getItem("info3") )
  }
});

In a standard Vue.js application, the root instance must be created. The initial code typically looks like this:

const rootInstance = {
  data() {
    return { /* Declare reactive properties */ };
  },

  methods: {
    attemptAfterLogin() {
      // do something here.
    }
  }

  template: `<div>Hello App</div>`
};

const app = new Vue(rootInstance);

The objective is to integrate this initialization code into the message event handler. When merged into a single code, it would appear like this:

const rootInstance = {
  data() {
    return { /* Reactive properties */ };
  },

  methods: {
    attemptAfterLogin() {
      // do something here.
    }
  }

  template: `<div>Hello App</div>`
};

// Initialize Vue.js app
const app = new Vue(rootInstance);

window.addEventListener('message', function(event) {
  if (event.origin == 'http://localhost:8080') {
    document.getElementById('output').innerHTML = event.data;
    localStorage.setItem("info1", event.data.userData.info1);
    localStorage.setItem("info2", event.data.userData.info2);
    localStorage.setItem("info3", event.data.userData.info3);

    // Mount the application
    app.$mount(document.querySelector("#app"));

    // Notify the Vue.js app that localStorage is now set.
    app.attemptAfterLogin();
  }
});

This is just one approach. Additionally, you can have a simple loader animation until your inner iframe receives the message.

By the way, it's recommended to use addEventListener instead of onmessage when listening for events.

In essence, regardless of the front-end framework, the aim is to have a single entry point/function to load your application.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting issue: Displaying input based on selected option not functioning

<custom-select label="Target Type" v-model="targetType" name="targetType" placeholder="Select Target Type" data-test="overall-type-input" :options="targetTypeOptions ...

What steps should be taken in VUEjs if the API response is null?

There's a method in my code that retrieves a token from an API: let { Token } = await API.getToken({ postId: postId }) if(){} Whenever the token is null, I receive a warning in the console saying "Cannot read property 'Token' ...

Telerik Nested perspective

Here is the code snippet that I am currently working on, which involves a nested grid from Telerik: I've encountered an issue with using JavaScript to locate and interact with controls named "PreviousDate" and "DateofBirth". <%@ Page Language="c# ...

Eliminate specific content from within a div tag

Looking for a solution with the following HTML. <div id="textDiv"> <p> MonkeyDonkey is not a bird. Monkey is an animal. </p> </div> In this case, I am trying to delete the word "Donkey". I attempted the code below but it did no ...

Building XML using PHP with relatively extensive information stored in JavaScript

Similar Question: XML <-> JSON conversion in Javascript I have a substantial amount of data stored in JavaScript that I need to convert into an XML file on the PHP server. The process of transforming the data into a JSON object, sending it to PH ...

Unable to display "xyz" using console.log() function upon button click

Why isn't the JavaScript function being executed in this code snippet? <form> <select type="text" name="month" id="month"> <option value="01">January</option> <option value="02">February</option> ...

- Challenges with internal systems

I have a dialog window where I want to display a confirm dialog when clicking Cancel. To achieve this, I am creating a div element with some text that should be shown in the confirm dialog. However, the issue I'm facing is that the text intended for t ...

Trouble with selecting inputs within a Div Element

Could you please review the code below and help me understand why I am unable to retrieve the ID of the selected radio buttons using this.id? <div id="pay" class="btn-group" data-toggle="buttons"> <label class="btn btn-primary"> < ...

Create-react-app unable to activate Service Worker

I've been utilizing the power of create-react-app to create my react.js project. Whenever I use the command npm run build, it automatically integrates a service-worker for progressive web app functionality in the production build. Everything was runn ...

What is the best location to insert the code for toggling the text on a button?

I'm looking to update the button text upon clicking. When the button is clicked, the icon changes accordingly. I want the text to change from "Add to list" to "Added to list". I attempted to implement this functionality with some code, but I'm un ...

Utilizing various layouts in ASP.NET MVC with AngularJS

I am setting up two different layouts, one for visitors and one for management. Routes: app.config(['$routeProvider', function ( $routeProvider) { $routeProvider .when('/', { templateUrl: 'Home ...

Primary tag badge using Bootstrap design

I am currently following a React tutorial by Mosh, where he is using the badge badge-primary class in a span tag. import React, { Component } from "react"; class Counter extends Component { state = { count: 0, }; render() { return ...

What is the process for implementing pagination in vue-tables-2 with a Laravel REST API?

I'm looking to implement pagination on Vue server-table using a Laravel endpoint. How can I achieve this? Below is my component setup: <template> <div> <v-server-table :columns="columns" url="/object/find" :options="option ...

Display the information in the second dropdown menu once the selection has been made in the first dropdown menu

I've successfully implemented a feature where selecting an option from the first drop-down list populates the second drop-down list accordingly. The HTML code snippet is as follows: <select size="1" id="BodyPart" title="" name="BodyPart"> ...

Outputting an object using console.log in Node.js

When I print the error object in nodejs, the result of console.log(err) appears as follows: { [error: column "pkvalue" does not exist] name: 'error', length: 96, severity: 'ERROR'} I'm curious about the information enclosed ...

Unable to render data in HTML page using Vue component

home.html: <body> <div id="app"> {{ message }} </div> <div id="counter"> {{ counter }} </div> <script type="text/javascript" src="https://cdn.js ...

Issue observed: React Map layer is not loading until mouseEnter event happens

The map is displayed with the color fill only when a mouse enter event occurs. How can I make it trigger on load instead? I am working with react-simple-maps, and the JSON data is successfully loading the map on mouse enter. You can find the source code ...

"What is the best way to retrieve the value of a div element with jquery

Attempting to retrieve the value of a div using jQuery in Chrome console from this HTML: <div class="col-md-3"> <div class="vou-col" style="cursor: pointer"> <h4>Free Large Bucket</h4> <span class="sku-info">Voucher ...

TinyMCE - Utilizing selection.setContent along with getContent for the Warp Button

I am looking to implement a button that will wrap content with all tags. Snippet of Code: editor.addButton('MobileToggleArea', { text: '<M>', icon: false, onclick: function (){ editor.selection. ...

Integration of Angular.js functionalities within a Node.js application

After working on my node.js app for a few weeks, I decided to add some additional features like infinite-scroll. To implement this, I needed to use packages in node.js along with angular.js. So, I decided to introduce angular.js support to the app, specifi ...