...

View Full Version : Javascript code for fetching the page URL from an IFRAME with cross domain



ananthakrishnan
03-22-2012, 05:45 AM
I'm facing an issue with fetching the page URL from an IFRAME with cross domain.

Is there any approach/ any ways to achieve this?

Old Pedant
03-22-2012, 06:36 AM
You mean as in the case where the page that is sitting in the <iframe> has changed the URL?

Sorry, you are out of luck. Cross domain scripting is simply not allowed by modern browsers.

felgall
03-22-2012, 07:10 AM
To handle cross domain scripting in JavaScript, modern browsers introduced postmessage().

Example of code in the JavaScript on the sending domain to send the data (sending from a.example.com to b.example.com where the sending page was originally opened by the receiving page):


opener.postMessage('Work Done','http://a.example.com');

Example of code on the receiving domain to receive that message and just for the purpose of the example we display it in an alert:


msg_process = function(event) {
if ('http://b.example.com' === event.origin) {
alert(event.data);
}
}
addEventListener('message', msg_process, false);

For an iframe you'd substitute the way you normally expect to reference the other frame in place of opener.

Note that this only works in modern browsers - older browsers have no cross domain access.

Old Pedant
03-22-2012, 07:24 AM
It also only works if you control the code for both domains.

In this case, for example, the code in the page that sits in the <iframe> would have to call that postMessage() in order to send the message to the main window.

I admit I keep forgetting about postMessage, but I do so for the simple reasons that (a) if I have control of both domains, there are other ways to send messages [server side] and (b) if I don't have control of both, then postMessage is useless.

(And by "have control" here, I mean having at least the ability to ask the owner of the other domain to add the postMessage to her/his page.)

felgall
03-22-2012, 08:59 AM
I admit I keep forgetting about postMessage, but I do so for the simple reasons that (a) if I have control of both domains, there are other ways to send messages [server side] and (b) if I don't have control of both, then postMessage is useless.

There are situations where you only need control of the sending domain. The receiving domain doesn't have to check the origin of the message and so someone could set up a widget designed to display in an iframe and allow any page displaying it to postMessage() to it to provide information on exactly what the widget should do. In that situation the receiving domain would be set up to receive messages from ANY domain and so anyone could use postMessage from their domain to it. Since the domains calling it need to tell it who they are it would be able to communicate back as well.

I agree that there are other ways to do it via the server when you have control of both domains but postMessage could work out to involve a lot less JavaScript code (not to mention the server side code) if all that is required is to pass info client side without needing a copy of it on the server - of course then there's that antique browsers don't understand it as it is a relatively new addition intended to simplify the communication between domains in specific types of situation (ones where there is already a more complex alternative such as sending via the server).

Old Pedant
03-22-2012, 09:28 PM
Absolutely agree with you. Just that I (personally) have never been in a situation where all the pieces fit together to use this. Every time I've wanted content from some other domain, the other domain's owner has been completely uninterested in my needs. So I've used server-side cross-scripting, instead. Of course, even that doesn't always work. Google, for example, has some really really clever detection in place and almost always won't respond to such server-side requests (except in the case of published APIs, of course).

felgall
03-22-2012, 09:35 PM
(except in the case of published APIs, of course).

I haven't seen any published APIs thatallow the useof postMessage yet but I expect some will start to show up in the next year or two. I would expect that it will be in that area where it will turn out to be most useful.

Old Pedant
03-22-2012, 10:52 PM
We can only hope. That would be nice. So that we could use such APIs from web pages directly, instead of needing the server side API usage. As soon as MSIE 7 disappears, they'd actually be usable in most sites.

rnd me
03-23-2012, 07:13 AM
Just that I (personally) have never been in a situation where all the pieces fit together to use this.

one thing i use postMessage for is to store data across domains without a server-side component. I use a lot of bookmarklets and code that get distributed to several domains. it can be very nice to have the capability of storing and fetching up to 5MB of json data from anywhere.

all you need is a static HTML file (http://danml.com/storage/) to serve the "virtual db server" from. feel free to use (deep-link) the one i linked (http://danml.com/storage/), or download it to your own server.

here's a typical procedure that can mount the data via a store() function:

if(!window.store){window.store=(function(){

var frame_url="http://danml.com/storage/"; //customize this if needed
var is_ready=false;

function addEvent( obj, type, fn ) {
var ename= type.replace(/^on/i,"");
var resp = obj.attachEvent ?
obj.attachEvent( "on" + ename, function(){ return fn.call(obj, window.event )} ) :
obj.addEventListener(ename, fn, false );
if(!resp){ obj["on"+ename] = fn; }
}


var elm= document.getElementById("_storage_iframe");
if(!elm){ elm=document.createElement("iframe");
elm.id="_storage_iframe";
elm.setAttribute("style","position:absolute;z-index:-9;height:1px;width:1px;opacity:0.01;left:-99px;top:-99px;");
document.body.appendChild(elm);
}

elm.src=frame_url;

var callBacks={};

addEvent(window, "message", function(event) {
var res=JSON.parse(event.data);
if(res.key==="STORAGE_READY"){return is_ready=true;}
if(res.key && callBacks[res.key]){ var cb=callBacks[res.key]; delete callBacks[res.key]; cb(res.value); }
return false;
} , true );


function _store(key, val, cb){
if(!is_ready){return setTimeout(function(){_store(key, val, cb);}, 100);}
if(!cb && typeof val=="function"){cb=val;val=undefined;}
callBacks[key]=cb||String;
elm.contentWindow.postMessage( JSON.stringify({ key:key, value:val }), "*" );
}

return _store;

}());
}//end if store defined?


actual usage demo
run this code (along with the code above) in firebug or "F12 tools" or chrome inspector from several different websites:



store("hist", function(stack){

stack=stack||{};

stack[location.href]=new Date().toString();

store("hist", stack);

alert(JSON.stringify(stack, null, "\t"));

});


you can watch as several URL and times stack up with each fresh execution of alert().

while you cannot share the info like you can using a DB, at least you can persist it locally on one computer, and that alone can be quite handy (and cheap and safe)...

ananthakrishnan
03-29-2012, 11:25 AM
Hi rnd me/Old Pedant/felgall,

Thanks for your response.

I also need to fetch the meta tag information from an Iframe.

Let me also clear the procedure once again.

Firstly, my javascript is inside an Iframe (which is basically from cross-domain). Now, I'm executing that Iframe from a page (which is again from another cross-domain). Here the inner Javascript should be able to fetch the Meta tags of the main page.

Is there any ways for doing this?

Thanks,

Ananth

ananthakrishnan
03-29-2012, 11:26 AM
Also, anyone knows about the Stub file concept. How to implement this?

It would be great if I got some response.

Thanks,

Ananth



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum