I am developing a chrome extension, in which I am working on two windows. The second window has been opened by the first window, through JavaScript. What I want to do is, to get the URL of the window opened by the first window. I have tried some methods, like using cookies, local Storage but I failed because of the cross origin policy. Now I came to know after a tutorial on postMessage() API of JavaScript that it overcomes the policy of cross origin. What I am doing is, I am accessing the URL from my localhost, and trying to get the URL of any other site, or possible I can get a simple message from that, but its not working for me as well. As I am not even getting any error and not even a warning. My goal is to get the URL, after when the child window loads. I will require on load function, so that I can check when the window is loaded right after it send me the message to my current window where it has been opened from.
My Code
var win = window.open('https://javascript.info/','_blank');
win.focus();
win.postMessage('The URL of the window is : ' + document.URL,'http://localhost.com/ext_files/index.php');
window.addEventListener("message", function(event) {
if (event.origin != 'https://javascript.info/') {
// something from an unknown domain, let's ignore it
return;
}
alert(event.data);
});
Related
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.
I am looking for a way to access a button inside the iFrame and trigger a click event when that button is clicked inside the iFrame that is on another domain.
Trying to go deeper into an element within the iFrame has proven difficult. Has anyone had success taking it this far?
Use an ajax call to the iframe's src to get its content, and render it as part of your site (which you then can hook).
You can't access the contents from an iframe from a different domain directly because that would be a security violation.
If i understand your requirements correctly
You can add a $('#iframe').load(function(){} which will watch the loading of iframe into your DOM.
After loading iframe you can attach an event listener to button click
var iframe = $('#iframe').contents();
iframe.find("#button").click(function(){
//write code to close the popup
});
The above process can be summarized as follows
$('#iframe').load(function(){
var iframe = $('#iframe').contents();
iframe.find("#button").click(function(){
$('#popup').close() //May depend on your popup implementation
});
});
The Problem here is that the same-origin policy blocks scripts from accessing contents of site with other origin.
Actually origin consists of the following parts.
origin:<protocol(http/https)>://<hostname>:<port number>/path/to/page.html
The origin is considered to be different if protocol,host name and port number are not same.
In such cases you can not access the contents of one website from other website due to same-origin security policy.
In order to overcome it you have to use parent-child communication using window.postMessage().
FYI : https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage.
The Window.postMessage() method safely enables cross-origin communication.
Suppose that your parent website is example-parent.com and In Iframe your loading website example-iframe.com and let both are using http protocol. Below is how I solved the problem.
In parent website add event listener for messages to receive as follows.
window.addEventListener('message',receiveMessage,false);
function receiveMessage(event){
var origin = event.origin || event.originalEvent.origin;
if(origin.indexOf('http://example-iframe.com')>=0) // check if message received from intended sender
{
if(event.data=="intended message format") // check if data received is in correct format
{
// call functionality that closes popup containing iframe
}else{ // data received is malacious
return;
}
}else{ // message is not received from intended sender
return;
}
}
From Iframe post message to the parent website as follows.
Post message syntax : otherWindow.postMessage(message, targetOrigin, [transfer]);
function sendMessage(){
parent.postMessage('intended message format','http://example-parent.com');
}
Use postMessage() properly,otherwise it may lead to cross-site scripting attack.
I am Sorry to say this to you but, you can't.
Since that will be violating CORS (Cross-origin resource sharing) rules that browser has set and it won't let you break those. Since its the almighty.
It will give an error 'Access-Control-Allow-Origin' in your console .
Hope you find it helpful.
Still if want to do something in your website you can ask below, I might give you an alternate to do so.
What i wanted to do:
From parent window on user click open new window source is Third Party URL (different domain)
User Authenticate in Popup and then Third party submit success data on Redirect page. (Like Twitter)
From Child Window (PopUpWindow) i have to send data back to Parent window.
what i did
var windowReference= window.open('https://ThirdPartyURL', 'CrossDomain', 'width=840,scrollbars=yes,top=0');
window.parentMethod= function (input) {alert(input)}
window gets open in new window User gets authenticate and get returned data on Redirect Page
on Redirect page (child window)
window.opener.parentMethod(response);
in Firefox its working but in IE
window.opener null . Reason is cross domain . if Third party URL is in current domain then it works fine but if its cross domain windowReference gets null
to get it working i have to change Internet Settings->Security->Check Enabled
its almost impossible to do at every client machine.
i have tried to used Postmessage but it has support for IE10 and in IE8 and 9 it has support for Iframe where as in my case Third party has disabled IFRAME embedding.
can some one help me how to over come this issue . any help will be appreciated
Short answer: you can't. The cross origin policy has as a reason exactly not allowing you to do what you want (the so another site won't run js on yours and the other way around).
To get around that you need to find another way to send data (usually server side -> curl requests).
how can I check if the document in new window is ready AFTER the document reloads.
Here is my example:
I need to get a search result page to new window from some site (it's cross-domain). I need to first make POST request (they probably store search params in session) and then go to reslut page.
Here is my code:
var windowname = "window"+(new Date().getTime()); // so I can open multiple windows, not very relevant
var new_window = window.open("", windowname); // prepare named window
// prepare form with post data targeted to new window
var dataform = $("<form method='post' target='"+windowname+"' action='https://www.ebi.ac.uk/chembldb/compound/smiles/'><input name='smiles' value='"+$("#id_smiles").text()+"'></form>");
// Need to get the form into page for Mozilla, webkit allows to submit forms that are not in page
$("body").append(dataform);
// submit the form and remove it, no need to keep it
dataform.submit().remove();
// form opens in my new window
$(new_window.document).ready(function(){
// this is carried out apparently too soon, because the POST data didn't work
// when I use timeout (commented below, but i don't like this solution) it works
window.open("https://www.ebi.ac.uk/chembldb/index.php/compound/results/1/chemblid/asc/tab/smiles", windowname);
// setTimeout( function(){window.open("https://www.ebi.ac.uk/chembldb/index.php/compound/results/1/chemblid/asc/tab/smiles", windowname)}, 1000);
});
On that site the first make POST request with AJAX and then they simply, but since it's cross-domain, it is impossible for me.
I believe this is not possible. Even some browser throw exceptions if you use reference of new_window (cross domain).
I got following exception. while trying to access reference of new window with url http://www.google.com (Browser Chrome). and reference has no property with it.
Unsafe JavaScript attempt to access frame with URL http://www.google.co.in/ from frame with URL Document ready in new window, cross-domain. Domains, protocols and ports must match.
You can run the javascript code which is in cross domain, for that you should use either JSONP concept ( http://en.wikipedia.org/wiki/JSONP )/ Cross Origin Resource Sharing( http://en.wikipedia.org/wiki/Cross-origin_resource_sharing ).
Just few changes should be done in apache server settings.
I'm using the following code to open a blank window from a "secure" page:
$('#previewTemplate').click(function () {
var preview = window.open('', 'PreviewTemplate', 'width=800,height=400,scrollbars=1');
var html = '<html><head><title>Preview</title></head><body>' + $("#textbox").val() + '</body></html>';
preview.document.open("text/html", "replace"); preview.document.write(html); preview.document.close(); return false;
});
The blank window is opening as a secure page (preview.document.location.protocol="https:") so IE is barking about the mixed content because I have a non-secure image in the page. I'm trying to open up the blank window as a non-secure window. Trying to change the location.protocol to "http:" or location.port to 80 doesn't seem to work. Is it possible to open up a blank "non-secure" window from within a secure page?
If the main window was https and the child window was http, the same origin policy would prevent the two from communicating with each other. i.e. those calls to preview.document.open would never work.
Three options:
host the image from the same https
domain as the parent window.
Instead of dynamically writing to the child window, just host a page on
the same server as the image. Even
if you can only put static html there
for whatever reason, some basic
javascript could be used to read the
url's query string and get the value
of textbox.
Read up on window.postMessage. Only works
in more modern browsers though.