Dynamically pass iframe url parameters to parent URL - javascript

I'm new with iframe interactions with parent, so let me explain the issue I'm facing in simple terms:
I have a site with an iframe. How can I use JavaScript or jQuery code to dynamically change my parent URL depending on what the user clicks in the iframe?
For example, if my parent URL is parent.com?page=1&currency=eur then my iframe will automatically be iframe.com?page=1&currency=eur, but the user can click another link inside the iframe. If the user clicks on a link and the iframe src changes to iframe.com?page=another_page, I want the parent URL to dynamically change to parent.com/page=another_page or parent.com#page=another_page. In other words, I pass all iframe URL parameters to parent.
Can anyone help me with this?
I have full control over parent window and can add some code to child as well but they're not on the same domain.
Thanks

You can use window.postMessage to achieve interaction between parent-iframe/child window across 2 different domains.
In your case, since your child is modifying your parent, you should set up a listener on your parent page like so
window.addEventListener("message", (event) => {
if (event.origin !== "http://thisisyourchilddomain.com") // You must check for the sender's origin or your website could be exploited !!
return;
// do something
}, false);
And in your child page, you would call the method window.postMessage
parent.postMessage("hello there parent! please perform a redirect with the following params...", "http://thisisyourchilddomain.com");
Note that parent is a global here that you can access from your child. Also, you can pass an object to the first parameter of postMessage({key:value}, ..)
Examples were taken and modified from the link to window.postMessage (mozilla).

Related

How can I get the reference of the opened child window within the parent window?

I need to update the data on the child window from the parent window.
For this purpose I need to get the reference of the opened child window and pass the info to the child function named UpdateInfo().
Here is the row that opens the child window in parent web page:
window.open("HTMLPage2.htm" , "child" , "width=200, height=100")
Any idea how can I get the reference of the opened child window within the parent window?
P.S. I don't know if my approach is right; is there a better approach?
window.open returns a reference of the child window. You can use something like this:
var child = window.open("HTMLPage2.htm" , "child" , "width=200, height=100");
child.updateInfo(...);
This is possible only if the child's URL conforms to the Same-Origin Policy.
EDIT:
If the child is not from the same origin, you can still communicate with it via the window.postMessage() API. This enables you to send a message event to the child-window, and the child can listen to that event and invoke custom functionality.

Cross domain postMessage, identify iFrame

I use postMessage to send events from an iframe to it's parent document. I have control over both sides but the content comes from two different domains.
My simple problem is, that i can not identify the iFrame inside of it's parent callback method. The implementation looks like this:
In the iFrame:
parent.postMessage(JSON.stringify({action: "closeView" }),'*');
In the parent window:
window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
return;
// Parse message back to json
var messageObject = JSON.parse(event.data);
var source = event.source;
/* this is returning: Window -URL- */
console.log( source );
/* This will throw Permission denied, although this code is inside of "parent" */
console.log(source.parentNode);
},false);
I want to identify a certain parent element of the iframe, which is (logically) inside of the parent document.
When i try to use event.source.parentNode or some jQuery on said object, Firefox says, i can not do this to prevent XSS, error: Error: Permission denied to access property 'parentNode'
How can i get the parent element of the iFrame, that triggered the postMessage event listener?
you can use window names for this, as they pass from iframe tag to iframe context.
parent doc:
<iframe name=fr2 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20window.name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<iframe name=fr3 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<script>onmessage = function(e){ // use real event handlers in production
alert("from frame: " + e.data.name);
};</script>
iframe doc:
<html>
<script> parent.postMessage({name: name}, "*");</script>
</html>
which alerts "fr2", then "fr3".
you can then easily use the name attrib to find the iframe in the parent DOM using attrib CSS selectors.
illustrative demo of window.name+iframe concept: http://pagedemos.com/namingframes/
this painfully simple approach is also immune to issues arising from same-url iframes.
As per my understanding this may be try
here suppose your main window's url is www.abc.com\home.php
<body>
<iframe src="www.abc.com\getOtherDomainContent.php?otherUrl=www.xyz.com"/>
</body>
getOtherDomainContent.php in this file need to write ajax call which get cross url content and push that content in current iframe window(getOtherDomainContent.php)'s body part.
getOtherDomainContent.php
Code:
<html>
<head>
//import jqry lib or other you use.
<script>
$(document).ready({
//getcontent of xyz.com
var otherUrlContent=getAjaxHtml("www.xyz.com");
$("body").html(otherUrlContent);
// further code after content pushed.
//you can easily access "parent.document" and else using parent which will give you all thing you want to do with your main window
});
</script>
</head>
</html>
Like seen in this thread: postMessage Source IFrame it is possible to compare each iframes contentWindow with event.source like this:
/*each(iframe...){ */
frames[i].contentWindow === event.source
But i did not like this too much. My solution for now looks like this:
In the iFrame:
parent.postMessage(JSON.stringify({action: "closeView", viewUrl: document.URL}),'*');
Update:
docuent.URL can become a problem, when you use queries or links with location (#anchor) since your current url will become different from the one of the iframe source. So Instead of document.URL it's better to use [location.protocol, '//', location.host, location.pathname].join('') (Is there any method to get the URL without query string?)
In the parent document:
window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
return;
// Parse message back to json
var messageObject = JSON.parse(event.data);
// Get event triggering iFrame
var triggerFrame = $('iframe[src="'+messageObject.viewUrl+'"]');
},false);
Each event will have to send the current iFrame URL to the parent document. We now can scan our documents for the iFrame with the given URL and work with it.
If some of you know a better way please post your answers.

jquery selector from iframe content to object content

I need the following:
I got a html document, in which I have an iframe and an object. Both, the iframe and the object contain separat html files.
Now I want to click a link in the iframe, and this should affect the links inside the object to hide.
How do I use jQuery selectors to select the links in the object html file?
Structure:
<html file parent>
<iframe> html site 1 with link to click</iframe>
<object> html site 2 with links to affect </object>
<html file parent>
Thanks in advance!
This is not possible if the domain of the iframe is different from that of your .
This is a javascript restriction.
For this to possible you need to have control on the url loaded in the iframe.
If it is of same domain then you can probably do that.
If you have control over the iframe's url try this.
First, have a look at window.postMessage. Using this, you may send an event from your iframe to the window parent target. Listening for that event in the window parent (when something in your iframe changed), you will then be able to access any element inside the object tag using a syntax like this:
$('object').contents().find('linkSelector')
Give your iframe an id, let's say myIframe:
<iframe id="myIframe"> html site 1 with link to click</iframe>
Get a reference to the iframe:
var myIframe = document.getElementById('myIframe');
Post a message from iframe:
myIframe.contentWindow.postMessage('iframe.clicked', 'http://your-domain.here.com');
Handler for iframe change:
var handleIframeChange = function(e) {
//
if(e.origin == 'http://your-domain.here.com') {
// Get reference to your `object` tag
var objContent = $('object').contents();
// For instance, let's hide an element with a class of `link-class-here`
objContent.find('.link-class-here').hide();
}
}
Listen on parent window for the event sent by the iframe:
window.addEventListener('iframe.clicked', handleIframeChange, false);
Haven't tested it right now (did this in the past, when I had control over iframe) but it should work, but as I said, only if you can have control over the iframe.

Click event in iframe

I'm trying to append the url of the parent page an iframe is located in based on the current url within the iframe.
This is all taking place on the same domain, so I don't think there should be any security issues.
EDIT:
My code now looks like the following:
function locator_url() {
var iframeUrl = alert(document.getElementById("dealer- locator").documentWindow.location.href);
var iframeUrlSplit = iframeUrl.split('/locator/');
window.location.hash = '#' + iframeUrlSplit[1];
};
$(document).ready(function(){
document.getElementById("dealer-locator").contentWindow.onload = locator_url();
});
Now the default src for the iframe is http://localhost/meade/locator/
The page the iframe is on is http://localhost/meade/dealerlocator/
The code works for the initial page load, the parent url is appended to localhost/meade/dealerlocator/#
However, when I click a link inside the iframe the parent url doesn't change, even though the href value in the iframe has.
The parent url should have it's hash updated to something like:
localhost/meade/dealerlocator/#results_list.php?showonly=US&tab=US&zip=&distance=10&state=&city=&name=
But that's not happening.
What am I missing?
Did you try:
document.getElementById("dealer-locator").contentWindow.onload = locator_url;
Well, if you need click events in your iframe, then you could do it this way:
Car.com
Then locator_url() gets called in the parent page. Same goes for using load events (I mean, load events that occur in the iframe context).

Passing Messages from iFrame Across all Browsers

I have an embed-able iframe that will be used on 3rd party sites. It has several forms to fill out, and at the end must inform the parent page that it is done.
In other words, the iframe needs to pass a message to it's parent when a button is clicked.
After wading through oceans of "No, cross-domain policy is a jerk" stuff, I found window.postMessage, part of the HTML5 Draft Specification.
Basically, you place the following JavaScript in your page to capture a message from the iframe:
window.addEventListener('message', goToThing, false);
function goToThing(event) {
//check the origin, to make sure it comes from a trusted source.
if(event.origin !== 'http://localhost')
return;
//the event.data should be the id, a number.
//if it is, got to the page, using the id.
if(!isNaN(event.data))
window.location.href = 'http://localhost/somepage/' + event.data;
}
Then in the iframe, have some JavaScript that sends a message to the parent:
$('form').submit(function(){
parent.postMessage(someId, '*');
});
Awesome, right? Only problem is it doesn't seem to work in any version of IE. So, my question is this: Given that I need to pass a message from an iframe to it's parent (both of which I control), is there a method I can use that will work across any (>IE6) browser?
In IE you should use
attachEvent("onmessage", postMessageListener, false);
instead of
addEventListener("message", postMessageListener, false);
The main work-around I've seen used involves setting a hash value on the parent window and detecting the hash value in the parent, parsing the hash value to obtain the data and do whatever you want. Here's one example of doing that: http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/. There are more options via Google like this one: http://easyxdm.net/wp/.
This is way simpler than that.
You say you control both the parent and the content of the frame you can set up two way
communication in javascript.
All you need is
yourframename.document.getElementById('idofsomethinginttheframe')
And then from inside the frame address anything outside it with
parent.document

Categories