Because sharing is caring

Executing Javascript from an external Iframe

Posted: January 21st, 2011 | Author: | Filed under: Javascript, Web Development | Tags: , , , , , | 3 Comments »

Whats the problem?

Maybe you’ve made a deal with a partner website, or you’re just loading a page from another server. The point is: You’ve got an IFrame on your page coming from another domain.
All is well (except for Google, they don’t like iframes) untill you want some client-side interaction coming from that page.

But now you’ve reached the point where you want some client-side interaction from that IFrame. “Great!” you say. I’ll just put JS in the IFrame, and I’ll be fine. But hold your horses cowboy, there’s 2 things stopping you as a great developer from doing so:

  • Don’t have you JS scattered, have it nice and organised, centralized
  • You’re visually constrained to the IFrame

So how do we execute JS on the parent frame?

Directly from the IFrame? You can’t! Sandbox specifications say you can’t call functions defined in pages coming from another domain (kind of like loading JSON/Ajax from another domain).

But in that problem also lies the solution: just load a Proxy page from the other server!
Let me make myself a bit more clear through some Graphs:

Normally, you’de have 2 pages, page A contains an Iframe to page B:
Page A to Page B
Now we’re introducting a Proxy page, on the same server as page A. Page B contains a IFrame to the proxy page:
Page A to B to Proxy
All Done! Now you can execute JS, like so:
all done

The Code!

So how do we do it? Here you go!
index.html (on your server)

<html>
	<head>
		<script type="text/javascript">
			function alertme(str)
			{
				alert("String: " + str);
			}
		</script>
	</head>
	<body>
		<iframe src="http://yourpartner.com/iframe.htm"></iframe>
	</body>
</html>

proxy.html (on your server)

<html>
	<head>
		<script type="text/javascript">
			function gup( name )
			{
			  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
			  var regexS = "[\\?&]"+name+"=([^&#]*)";
			  var regex = new RegExp( regexS );
			  var results = regex.exec( window.location.href );
			  if( results == null )
			    return "";
			  else
			    return results[1];
			}
			eval("top."+gup("execute"));
		</script>
	</head>
</html>

And finally!
iframe.html (on any other server)

<html>
        <head>
        </head>
        <body>
        Hi There!
        <iframe src="http://yourserver.com/proxy.html?execute=alertme(123);"></iframe>
        </body>
</html>

What you did there, I don’t quite see it

In the page on the other server, I pass a function call as an argument to my proxy.
My proxy then gets this function out of the parameter, and executes it through eval()!

Warning

Handle with care, allowing anyone to simply execute JS on/from your server through a parameter just opens up a whole new spectrum of XSS attacks.
That sandbox was created for a reason!


Those fancy GMail buttons, with actual buttons!

Posted: August 25th, 2010 | Author: | Filed under: css, Web Development | Tags: , , , | 1 Comment »

After my post about gmail buttons yesterday, my friend Steven started working on that code.

He came up with an improved version of my example, one that works with actual buttons! Let me demonstrate below:

CSS Code:

input[type="button"], input[type="submit"], button {
margin:0 8px 0 0;
padding:2px 6px;
 
text-align:center;
vertical-align:middle;
 
display: inline-block;
white-space:nowrap;
cursor: pointer;
 
outline:none;
color:#000;
border: 1px solid #bbb;
 
-webkit-border-radius:3px;
-moz-border-radius:3px;
border-radius:3px;
 
background: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#e3e3e3));
background: -moz-linear-gradient(top, #f9f9f9, #e3e3e3);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#e3e3e3');
 
border-top-color:#ccc;
border-bottom-color:#a0a0a0;
}
 
input[type="button"]:hover, input[type="submit"]:hover, button:hover {
border: 1px solid #636363;
}
 
input[type="button"]:active, input[type="submit"]:active, button:active {
background: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#f9f9f9));
background: -moz-linear-gradient(top, #e3e3e3, #f9f9f9);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e3e3e3', endColorstr='#f9f9f9');
}

HTML can be any of the following:

<input type="button" value="it's a button" />
<input type="submit" value="it's a submit button" />
<button>It's a button button</button>

See that code in action right here:

The link to Steven’s post: credit goes where credit is due

P.S.:I know the hover border doesn’t work here, it does work where I implemented the buttons. I’ll look at this later

Update: Xavier Bertels from Live Graphics also had a go at the buttons
This is becoming more and more of a team effort, love it!


JQuery UI tabs with selected by #location.hash

Posted: August 5th, 2010 | Author: | Filed under: Javascript, JQuery, Web Development | Tags: , , , | No Comments »

I’m using JQuery UI Tabs in an application.
I really love the implementation, never seen anything so easy.

If you want to make sure another tab but the first one is selected on page load, just give the ‘selected’ option like so:

$("#tabs").tabs({selected: 1});

For the second tab in the tabarray (counting starts with 0).

If you want to make your url’s do the following however: http://www.example.com/mytabbedpage.do#gotothistab. There’s no support from JQuery itself just yet.

I found a solution on Rootsmith Inc’s blog.
Especially sami‘s comment helped me:

1
2
3
4
$(’#my_selector’).tabs({
’select’: function(){$(this).index($(document.location.hash));},
‘load’: function(event, ui){document.location.hash = ui.panel.id;}
});

However, applying this loses your default tab.
My solution:

1
2
3
4
5
var selectedtab = 1;
if(document.location.hash!="" && typeof(document.location.hash)!="undefined" && document.location.hash!= null){
	selectedtab = $(document.location.hash).index() - 1;
}
$("#tabs").tabs({selected:selectedtab});

I know, I like to be thorough in my checks ;-)