Pass Window Reference Using PostMessage - javascript

I want to pass the Window reference using PostMessage but getting this exception
Uncaught DataCloneError: Failed to execute 'postMessage' on 'Window': An object could not be cloned.
below is my code:
var postWindow = window.document.getElementById('dummyId').contentWindow;
postWindow.postMessage(window, 'http://localhost:9090');
How to pass this Window reference?Any idea?

You can't. Too much stuff dangling off window does not fall into the supported types.
Pass the data you need, not absolutely everything.
I have main MainAPP application(running in 8080) in that i have a button,when i clicked that button its open a pop with new iframe and loading content from some other server(running in 9090).when i clicked the cancel button in popup,that popup has to be closed.so i need the window reference of parent(MainApp) in popup window.
So the page in the iframe needs to post a message to the parent window saying "Close me".
The event handler handler listening for the message then needs to remove the iframe.
Make the JavaScript belonging to the window containing the frame responsible for removing the frame.

The postMessage function exist to talk cross origin. It is a tool to be able to go around security (in a secure way) when for instance an iframe has a site of different origin.
You do not want to try to send the window object into it, even if you find a way.
The restriction exists so that any iframed site cannot access and modify content of its parent window.
Instead, you should define an API of messages that can be sent and handled by the other site. But it is up to the other site to handle them by itself. That way communication can be more restricted and secure.

Related

How to receive postmessage inside Facebook in-app browser?

I'm trying to send postmessage from the opened window to opener in facebook app browser, but the "opener window" never receives messages. What can be the cause of the problem?
Receiver side:
window.addEventListener('message', function (e) {
window.console.log("on message: " + e.data);
}, false)
Sender side:
window.opener.postMessage('any Message', document.location.origin);
It's hard to tell without seeing more of your code, but as this Opening facebook connect window via javascript? answer states, if you're trying to access the oAuth page, it's not possible.
Show us where you get the variable window.opener, that might add some context.
If you opened it from window.open(/page/), it appears that it is specifically blocked: How do I get around window.opener cross-domain security
as mentioned in that question:
NOTE
Social signups do not work for google, FB, etc within an iframe. I
believe they disallow them for security reasons.
Also from window.opener is null after redirect
window.opener is removed whenever you navigate to a different host
(for security reasons), there is no way around it. The only option
should be doing the payment in a frame if it is possible. The top
document needs to stay on the same host.
But as mentioned in the second answer quoted, instead of using window.opener on the opened page, do everything from the origninal page, and (IF you have access to the source of the popup), make an onmessage on the other page, like mentioned in the accepted answer there, that the correct way to do it is only in reverse:
Do it the other way around. Track the state of the child popup window
from the main (opener) window, and you could easily know when the
child window has been navigated back to you domain, so you could
"talk" to it again. But don't close the child window by itself. Let
the opener window obtain the result from the child window and then
close it.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#Example
For example, in your started page, do something like:
var popup = window.open(/*some URL*/);
popup.postMessage("hi");
addEventListener("message", function(e) {
console.log(e);
e.source.postMessage("Hi there"); //official workaround for window.opener on other page
})
then in your "/some URL/" source code page, do something like:
addEventListener("message", function(e) {
console.log(e);
e.source.postMessage("hi back");
});
and just play around with that strategy, but it appears window.opener is out of the picture. Just try console.logging it, it just say null.

Allowing an Electron-hosted webapp to call window.open and to use the result as if it were a regular Chrome window

The webapp that I'm hosting in Electron's webview tag makes calls to window.open. However, since window.open can't be invoked from inside of an iframe in Electron, I am forced to override window.open, so that it sends a message to the renderer process that hosts the webapp and tells it to invoke window.open and send back the result.
From my renderer: webContents.send("my-channel", myWindow);
However, it doesn't appear that I can simply send back the entire window to the webapp. The window that gets sent to the webapp doesn't have any of the functions that BrowserWindowProxy is supposed to have (e.g. close). I imagine that it would be strange if it did have a close, since close would need to know to escape the webapp (through some means) and alert Electron's renderer/main process that a window needs to be closed.
I want the window that is sent to the webapp to behave like a more-or-less regular Chrome window (namely, I want it to have the same public api). So, my first question was how to get such a window to the webapp.
The solution I came up with is the following. I still call window.open in the renderer process, but instead of passing back the resulting window, I pass back an object that has a windowId property, which is set to the window's id. When that object gets to the webapp, it goes through a little intermediary that sees the window object and sets some properties (like close, focus) that internally send a message to the renderer process to perform the relevant operation (via a function exposed through the preload script). Something like:
myWindow = {
windowId: 1,
close: function() {
sendActionFromWebviewToMain("close", this.windowId);
}
}
The next problem I ran into was that the window returned by Electron's window.open, unlike the one returned by new BrowserWindow(...), does not appear to have an id. The source code references a guestId, but I have no way of accessing it.
How can I use window.open to create a window that the webapp can interact with? Am I forced to create the window using the BrowserWindow constructor?
This issue has since been fixed.
All I need to do now is set the nativeWindowOpen and allowpopups attributes on my webview tag, and I can use the native window.open.
<webview webpreferences="nativeWindowOpen=yes" allowpopups />

JavaScript problems when launching site in iframe

I have set up an Articulate Storyline course (a Flash version accessed using the page "story.html" and an HTML5 version accessed using "story_html5.html"). It works fine when run directly, however, when I try to run everything in an iframe on the company server (linking to the course files on my personal server) I get JavaScript errors:
The course uses player.GetVar("HTML5spelaren") to access a variable called HTML5spelaren, which is located on the story_html5.html page itself. When running in an iframe I get a "Permission denied to access property 'HTML5spelaren'".
Finally the course uses the JavaScript var newWin=document.window.open("report.html", "Kursintyg"); to display a course completion certificate in a new window. When running in an iframe however this results in a "Permission denied to access property 'open'".
Is there a way to rewrite the JavaScripts to get around this? I need to be able to detect if the course is running in Flash or HTML5 mode (that's what I use the variable in story_html5.html for), as well as being able to use JavaScript to open a new page from within the iframe when clicking on a link.
Page structure:
https://dl.dropboxusercontent.com/u/11131031/pagestructure.png
/Andreas
There's a way for different domains to speak to one another via javascript. You can use postMessage: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
In your case, in story.html or story_html5.html could use something like:
parent.postMessage(HTML5spelaren, parent_domain);
and you add an event listener in the company page:
window.addEventListener("message", receiveMessage, false);
And in receiveMessage function you retrieve the data that you need. Something like:
function receiveMessage(event){
your_variable = event.data
}
Same logic can be probably be applied to your popup.
You can post from child to parent or from parent to child.
My guess is that content you're linking to in the iFrame is on a different server/domain. If so, the error is a security feature to stop cross-site scripting (XSS) attacks.
Consider putting both the parent iFrame and the articulate content (child) on the same server. This should eliminate the problem.

trying to use window.opener technique to call parent js function from child popup window?

I'm trying to use the js window.opener technique to return a selected value from a child window back to a parent js function. Here's a url to a zip file where I set up a basic poc:
https://www.dropbox.com/s/gle9sou3gj770ej/WindowOpenerPOC.zip
LaunchPage.html is used to open ResolveCaseDialog.html. The Submit button on ResolveCaseDialog submits the selected "Resolution Type" value to window.opener.ProcessReturnValue().
However, when I click the Submit button, the ResolveCaseDialog js throws the following exception: "Uncaught SecurityError: Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match."
Can you please take a look at this setup and let me know if there's a trick to making this work that I'm missing?
I'm on a similar problem too, you have to use
opener.ProcessReturnValue();
instead of
window.opener.ProcessReturnValue()
This works for Internet Explorer but doesen't work on Chrome.
Now the problem is that is not specified the port.
We are a step forward but the problem isn't resolved yet.
Here there is an example:
call opener function
The main page is testA, that calls testB.

How can child window call a function on its parent window?

I have a local HTML running in IE browser. When the local HTML opens a child window which loads a page on a remote HTTP server. After a few user interactions in the child window, the final remote page runs a JavaScript to close the child window and I would like to call a function in the parent window to pass back some info before closing.
I thought I would be able to simply make the following call in the child window
window.parent.CallbackFunct();
However, the call doesn't work. I did some research and some mentioned that if the parent window loads HTML through file:\ (which is my case), the child window cannot call parent window functions due to same origin policy.
JavaScript window.opener call parent function
My above link suggests to access all pages through HTTP://, but I cannot. The parent window has to access pages from the local file system.
Is there any way that I can make it work?
You may call a parent function from child window this way:
window.opener.your_function()

Categories