Array

Talking Across Domains

Must Read

Admin
Admin
Just post!

Client-side web applications have always been restricted from talking directly to scripts on other domains, a restriction designed to protect users.5 There are numerous clever ways around this restriction, including the use of server-side proxies and clever URL hacks. But now there’s a better way.

The HTML5 specification introduced Cross-document Messaging, an API that makes it possible for scripts hosted on different domains to pass messages back and forth. For example, we can have a form on http://support.awesomecompany.com post content to another window or ¡frame whose content is hosted on http://www.awesomecompany.com. It turns out that for our current project, we need to do just that.

AwesomeCo’s new support site will have a contact form, and the support manager wants to list all the support contacts and their email addresses next to the contact form. The support contacts will eventually come from a content management system on another server, so we
can embed the contact list alongside the form using an ¡frame. The catch is that the support manager would love it if we could let users click a name from the contact list and have the email automatically added to our form.

We can do this quite easily, but you’ll need to use web servers to properly test everything on your own setup. The examples we’re working on here don’t work in every browser unless we use a server. See the sidebar on the following page for more on this.

The Contact List

We’ll create the contact list first. Our basic markup will look like this:

<ul id=”contacts”>
<li>
<h2>Sales</h2>
<p>James Norris</p>
<p > j . n o r r i s@awesomeco.com</p>
</li>

If you don’t want to go through the trouble of configuring Apache instances or setting up your  own servers, you can use the simple Ruby-based servers included in the book’s example
code files. For instructions on getting Ruby working on your system, see t he file RUBY_README.txt within the book’s source c o d e files.

To start t he servers, first go into t he html5xdomain/contactlist a n d run the server.rb file like this:

ruby s e r v e r . rb

It will start on port 4567. You can then do the same for the server.rb in html5xdomain/supportpage, which will start on port 3000. You can edit the port for each of these by editing the server.rb file.

<li>
<h2>Operations</h2>
<p>Tony Raymond</p>
<p>t. raymond@awesomeco. com</p>
</li>
<li>
<h2>Accounts Payable</h2>
<p>Clark Greenwood</p>
<p>c .greenwood@awesomeco. com</p>
</li>
<li>
<h2>Accounts Receivable</h2>
<p>Herbert Whitmore</p>
<p>h.whitmore@awesomeco.com</p>
</l i>
< / u l >

On that page, we’ll also load both the jQuery library and our own custom application.js file and a simple style sheet. We’ll place this in our head section:

< s c r i p t type=”text/javascript”
charset= “utf-8″
src=”http://ajax.googleapis.com/ajax/1ibs/jquery/1.4.2/jquery.min.js”>
</script>

< s c r i p t t y p e = ” t e x t /javascript”
src=”javascripts/application.js”>
</script>
<link rel=”stylesheet” href=”style.css” type=”text/css” media=”screen”>

The style sheet for the contact list looks like this:

Ul{
l i s t – s t y l e : none;
}
ul h2, ul p{margin: 0 ; }
ul l i { m a r g i n – b o t t o m : 20px;}

It’s just a couple of small tweaks to make the list look a little cleaner.

Posting the Message

When a user clicks an entry in our contact list, we’ll grab the email from the list item and post a message back to the parent window. The postMessage() method takes two parameters: the message itself and the target window’s origin. Here’s how the entire event handler looks:

$ ( f u n c t i o n ( ) {
$(“^contacts li”).click(function(event){
var email = ( $ ( t h i s ) . f i n d ( ” . e m a i 7 ” ) .html ( ) ) ;
var o r i g i n = “http://192.168.1.244:3000/index.html”;
window.parent.postMessage(email , o r i g i n ) ;
} ) ;

You’ll need to change the origin if you’re following along, since it has to match the URL of the parent window.

Now we need to implement the page that will hold this frame and receive its messages.

The Support Site

The support site’s structure is going to look very similar, but to keep things separate, we should work in a different folder, especially since this site will need to be placed on a different web server. We’ll need to make sure you include links to a style sheet, jQuery, and a new
application.js file.

Our support page needs a contact form and an ¡frame that points to our contact list. We’ll do something like this:

<div id=”form”>
<form id=”supportform”>
<fieldset>
<ol>
<li>
<label for=”to”>To</label >
<input type=”email” name=”to” id=”to”>
</li>
< l i >
<label for=”from”>From</label>
<input type=”text” name=”from” id=”from”>
</li>
< l i >
<1abel for=”message”>Message</label>
<textarea name=”message” id=”message”x/textarea>
< / l i >
</ol>
<input type=”submit” value=”Send!”>
</fieldset>
</form>
< / d i v >
<div id=”contacts”>
<i frame src=”http://192.168.1.244:4567/index.html”x/i frame>
< / d i v >

We’ll style it up with this CSS that we add to style.ess:

#form{
w i d t h : 400px;
f l o a t : l e f t ;
}
#contacts{
w i d t h : 200px;
f l o a t : l e f t ;
}
#contacts iframe{
border: none;
h e i g h t : 400px;
}

f i e l d s e t {
w i d t h : 400px;
b o r d e r : none;
f i e l d s e t legend{
b a c k g r o u n d – c o l o r : #ddd;
p a d d i n g : 0 64px 0 2px;
}
f i e l d s e t > o l {
l i s t – s t y l e : none;
p a d d i n g : 0;
m a r g i n : 2px;
}
f i e l d s e t > o l > l i {
m a r g i n : 0 0 9px 0;
p a d d i n g : 0;
}
/ * Make i n p u t s go to t h e i r own l i n e */
f i e l d s e t i n p u t , f i e l d s e t t e x t a r e a {
d i s p l a y : b l o c k ;
w i d t h : 380px;
}
f i e l d s e t i n p u t [ t y p e = s u b m i t ] {
w i d t h : 390px;
f i e l d s e t t e x t a r e a {
h e i g h t : lOOpx;
}

This places the form and the ¡frame side by side and modifies the form so it looks like Figure 10.1, on the previous page.

Receiving the Messages

The onmessage event fires whenever the current window receives a message. The message comes back as a property of the event. We’ll register this event using jQuery’s bind() method so it works the same in all browsers.

$ (function (){
$(wi ndow).bi nd(“message”,function( e v e n t ) {
$ ( ” # t o ” ) .val ( e v e n t , o r i g i n a l Event, d a t a ) ;
} ) ;
} ) ;

jQuery’s bind() method wraps the event and doesn’t expose every property. We can get what we need by accessing it through the event’s originalEvent property instead.

If you open this in Firefox, Chrome, Safari, or Internet Explorer 8, you’ll see that it works extremely well. Now let’s make it work for IE 6 and 7.

Falling Back

To support IE 6 and 7, we’ll use the jQuery Postback plug-in, which emulates cross-domain messaging. We’ll use jQuery’s getScript() method to pull that library in only when we need it. To do that, we’ll just detect whether the postMessage() method exists.

First, we’ll modify our contact list.

i f ( w i ndow.postMessage){
w i n d o w . p a r e n t . p o s t M e s s a g e ( e m a i l , o r i g i n ) ;
} e l s e {
$ . g e t S c r i p t ( “javascripts/jquery.postmessage.js”, f u n c t i o n O {
$.postMessage(email, o r i g i n , w i n d o w . p a r e n t ) ;
} ) ;
}

The jQuery Postmessage plug-in adds a postMessage() method, which works almost exactly like the standard postMessage() method.

Now, let’s turn our attention to the support site. We’ll use the same approach here, pulling in the library and calling the newly added receiveMessage() method.

i f(window.postMessage){
$(wi ndow).bi nd(“message”,function(event){
$ ( ” # t o ” ) .val ( e v e n t . o r i g i n a l E v e n t . d a t a ) ;
} ) ;
}else{
$.getScript(“javascripts/jquery.postmessage.js”, functionO{
$.receiveMessage(
function(event){
$ ( ” # t o ” ) . v a l ( e v e n t . d a t a ) ;
} ) ;
} ) ;
}

That’s it! We can now talk across windows in a whole bunch of browsers. This is just the beginning, though; you can expand this technique to do two-way communication, too. Any window can be a sender or a receiver, so take a look at the specification and see what you can build!

 

 

Previous articlePreserving History
Next articleWeb Sockets
- Advertisement -

Latest News

Elevate Your Bentley Experience: The Bespoke Elegance of Bentayga EWB by Mulliner

Bentley Motors redefines the essence of bespoke luxury with the introduction of the Bentayga EWB's groundbreaking two-tone customization option—a...
- Advertisement -

More Articles Like This

- Advertisement -