HTML5: Messaging and Communications in Depth

HTML5: Messaging and Communications in Depth

with Bill Weinman

 


This course shows how to communicate between web pages, both within a single domain and across one or more domains, using the HTML5 Messaging API. Author Bill Weinman reviews security and the same origin policy, details cross-origin scripting techniques, and explores examples of cross-document messaging. The course describes how to register and send messages to listeners and handle errors.

show more

author
Bill Weinman
subject
Developer, Web, Web Development
software
HTML
level
Intermediate
duration
43m 19s
released
Jan 23, 2012

Share this course

Ready to join? subscribe


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi! I'm Bill Weinman and I'd like to welcome you to HTML5: Messaging and
00:08Communication in Depth.
00:09In this course we'll look at the HTML5 messaging application programming,
00:13interface including how messages work, the same-origin policy, and effective
00:19techniques for cross-origin scripting.
00:21The HTML5 messaging API provides an excellent tool for creating cross-origin
00:27applications safely and effectively.
00:29Learn how to use this powerful technology in HTML5: Messaging and
00:33Communication in Depth.
Collapse this transcript
Using the exercise files
00:00If you have access to the exercise files for this course, you can use them to
00:04follow along with the lessons as I present them.
00:07In order to follow along, you'll need to upload these files to a server and edit
00:11the files on the server instead of on your workstation.
00:14The technology presented in this course will not work without a web server.
00:18The examples in this course count on documents being served from different
00:22origins, so you must be able to set up your server with at least two domains
00:27using the same set of files.
00:29It's a good idea to have a text editor capable of editing over SFTP on a server.
00:34I use the excellent BBEdit or its free version, TextWrangler, on the Mac.
00:39On the PC I use Notepad++, which is also capable of editing on the server over SFTP.
00:45Here in the exercise folders you'll find a folder for the various chapters in the tutorial.
00:50The files inside the folders are generally organized by chapter, and many have
00:54start and done files as a beginning and ending place for that file.
00:59You'll want to start with a working copy of the start file, or a working copy of
01:03the file from the previous movie, and work with the copy so that you can start
01:08over again with a fresh copy if you need to.
01:11In the CSS folder, you'll find a simple CSS file that is used for all of the examples.
01:18Now I'm just going to page through this for you for the benefit of those
01:21who're typing this in.
01:24If you do not have access to these exercise files you may still follow along and
01:28create files of your own.
Collapse this transcript
1. Overview
Overview of HTML5 messaging
00:00HTML5 messaging allows you to create communication channels between objects and windows.
00:06It's used by many of the other HTML5 APIs, and may even be used to communicate
00:10between windows across domains.
00:13HTML5 messaging is accomplished by sending and receiving events.
00:17An event object has a data member which carries the message payload. The data
00:22member may be a string or it may be an object.
00:25Alternately, the data member may carry a JSON payload in order to represent more
00:30complex structured data.
00:32Note that Internet Explorer will only send strings, so you'll need to use JSON
00:36for any structured data.
00:38Listeners may be implemented in one of two ways.
00:41IDL listeners use the familiar onmessage = function syntax, and registered
00:46listeners use the addEventListener method.
00:50Keep in mind that depending on the objects you're working with, one of these
00:53methods may be supported better than the other, or even at the exclusion of the other.
00:58Senders are implemented with a simple postMessage method.
01:02It's very simple, and we'll discuss the details as we use it later on in this course.
01:06The event object itself has several members that you'll be interested in.
01:10The data member carries the message payload.
01:13The origin member carries a string representing the origin of the message--and
01:17we'll get into detail with this later--
01:20and the source member carries a proxy window object.
01:23HTML messaging is supported on all the major platforms, with few differences.
01:29Please note that while cross-domain messaging works on Microsoft Internet
01:33Explorer, it only works for frames; it does not work between documents in
01:37separate tabs or windows.
01:39Also note again that Internet Explorer will only send strings in the payload, so
01:43you'll need to use JSON for any structured data.
01:46HTML5 is simple to implement, but it does have some dangers to look out for,
01:51we'll cover these details in the rest of the course.
Collapse this transcript
Security and the same-origin policy
00:00Communicating across domains is a common problem for web application developers.
00:05Major browser vendors consistently implement a security policy called the
00:09same-origin policy.
00:11This prevents a script from one site from manipulating properties of a document
00:15loaded from another site.
00:17These different sites are called origins.
00:20This important security policy is effective in preventing session hijacking and
00:24phishing attacks, and like most effective security policies, it can be
00:29frustrating at times, like when you have a legitimate need to have scripts
00:33communicate with each other across different origins.
00:36So what exactly is an origin?
00:38An origin is made up of three components: the protocol, the host, and the port.
00:44If any of these three components are different, the origins are different.
00:47For example, if you have one document at this URL and another document at this
00:54URL, are they in the same origin?
00:57These two URLs are in the same origin. They have the same protocol, the same
01:01hostname and they have the same port number, which in this case is the default
01:06port number, port number 80, because none is specified.
01:09This URL is also in the same origin.
01:13The document itself is in a subdirectory, but that doesn't change the origin.
01:17The origin is not dependent on the directories; it's dependent only on the
01:20protocol, the hostname, and the port number.
01:23This document, on the other hand, is in a different origin.
01:26You'll notice that the hostname is different because it says blog.
01:30instead of www. Even though that's the third level of the domain, it's still significant.
01:36Any difference in the hostname will make a difference in the origin.
01:42This one is also a different origin because the protocol is different.
01:45Here it has https instead of http.
01:49And this one is also different. Even though the protocol and the hostname are
01:53the same, this one specifies a port number that's different than port number 80.
01:58So let's take a look at an example so that we can see what happens when you try
02:02to access an object across different origins.
02:07Here I have two documents that are loaded up at two different URLs that are on
02:12two different origins.
02:14First of all, let's take a look at the documents.
02:17Especially for those of you who are following along at home without the
02:20exercise files, I'm just going to page through this really quickly so that you
02:24can see the whole thing.
02:34And the same with the other document. That one is crossDomainOneError, and
02:38this one here is crossDomainTwoError, and you'll notice that it's a little bit different.
02:43Now there is a lot of support stuff in these two documents, but for the most
02:56part all they do is one loads up the other in a frame and then it tries to
03:01access the title from that other document.
03:05So here it is, loaded up in a browser, and they're on two different domains.
03:09The outer document is loaded up from the host
03:12one.3sn.net, and these are just a couple of domains that I have that I use. And
03:17the inside one is loaded up from host two.3sn.net.
03:21And you notice that the error message comes up here that says, "Permission denied
03:25to access property 'document'," and the reason for that is right here.
03:30Here we are, in document 2, and you'll notice in the init function, it loads up
03:34this variable windowOne from parent, which is the window object from the parent
03:39window that loaded up the frame.
03:41Remember, this document is inside of a frame.
03:44And then it tries to access the document title from that parent document,
03:50but it's in a different origin, and so you end up with this error.
03:55If instead I load them up from the same origin--and I can do that by coming in
04:02right here and just changing this hostname and I'll explain this trickery in a moment here.
04:08I'm just going to change it so that it's loading up a document off of the exact
04:11same domain and it's exactly the same document.
04:14And when I reload--I'm going to press Reload here--you'll notice that it works,
04:18and it's actually able to get that parent title.
04:20Now it's important that you understand how I have this set up, and you're going to
04:24need to do something like this in order to efficiently play with these examples
04:29and learn about the same-origin policy.
04:31I'm a big proponent of learning by experimenting and trying things and failing
04:36and figuring out why.
04:38So in order to do that, what you're going to need is to setup where you have the
04:41example files on a server--not on your local machine on your Desktop, but on
04:47a server that you're accessing using domain names--
04:50and on that server you have several different domain names pointing at exactly
04:55the same file system.
04:57And so what I've done here is I have a cloud server at Rackspace, and you
05:01can use any of the cloud server providers or whatever server you
05:05have accessible to you.
05:07And I've simply used a few domains, and I've set up Apache so that those few
05:11domains point at exactly the same file system.
05:13So I have all these files up there once, but they're actually accessible from
05:17one.3sn.net and two.3sn.net and three.3sn.net.
05:23Now in order to do this, you are of course going to need to use your own server
05:26and your own domain names. And you really need to have some kind of a setup like
05:30this in order to follow along with the examples in this course.
05:34So the HTML5 messaging API provides an effective way to work around the same-
05:39origin policy, so that you can communicate with your own scripts on different origins.
05:43We'll take a look at how this works in detail in the rest of this course.
Collapse this transcript
An example application
00:00This is a simple example application that implements cross-origin messaging
00:04using the HTML5 messaging API.
00:07So you can see we have two documents loaded up: one outside and one inside a frame.
00:13And again, because Internet Explorer won't even do this if they're in separate
00:17tabs, I've had to use frames for all of these examples.
00:21But just know that you can do exactly the same thing in tabs if you're using
00:26Firefox or Chrome or Safari or any other browser.
00:30But that doesn't work in Internet Explorer.
00:32So the way I have this set up is that these two documents are hosted on a server
00:38where the same file system is accessible from different domains, and so they're
00:42effectively in two different domains, at least from the perspective of the
00:45browser. And so the browser has its same origin policy in place and it's treating
00:51these as being from two separate origins.
00:54So the outer document is on a host called one.3sn.net, and the inner document is
01:01on a host called two.3sn.net.
01:03And you'll notice these timestamp log messages tell you the sequence of how
01:08things are happening.
01:09Document one loads up and then as part of its loading process, it loads up document two.
01:15And document two comes along as soon as it's loaded and it grabs the window
01:19object for its parent and it sends a message to its parent, and so it says over
01:23here at 035 milliseconds, "Message sent to windowOne."
01:28And then at 036 milliseconds it says, "Message from origin two.3sn.net."
01:34And then there's the message, "this is from windowTwo," and then it sends a
01:37message right back to windowTwo at 037 milliseconds, and then we have a message
01:43from origin one.3sn.net, and this is from windowOne.
01:49So here is an example of two different documents in two different domains
01:53sending data back and forth across that same-origin policy barrier.
01:58Let's take a look at the code.
01:59First of all, I'm just going to page through really slowly for those of you
02:02who are typing it in.
02:06This first document is called crossDomainOne.html, and this is the document
02:10loaded up at one.3sn.net.
02:20And again, you'll see a lot of support stuff in here that has more to do with the
02:23rest of course than perhaps this particular example.
02:27And then crossDomainTwo.html is loaded up on two.3sn.net, and this is the
02:34document that gets loaded inside of the frame.
02:46So taking a look first at crossDomainOne.html, the init function gets called down
02:53here at the bottom of the JavaScript. This is a technique that I'll use a lot
02:56window.onload = init. And so when it gets that onload event, that means that the
03:02document is all loaded up, and it calls this init function. And one of the first
03:07things that it does is it grabs the frame element and it sets its source to
03:12URLTwo, and that loads the frame.
03:14So the frame element is down here in the HTML, and you notice it does not have a source.
03:19And up here at the top of the JavaScript you'll see URLTwo, here on line 36, and
03:27that's the URL that gets loaded up for the second document.
03:30And I did this because it's a convenient way to be able to change the URL in one place.
03:36That actually makes it easier to experiment with it.
03:39Like for instance, if I wanted to change it to three.3sn.net--and I'll save that
03:45and go and load this up on the browser--it'll do it, and it gives me an error
03:50message, "message from un- trusted origin three.3sn.net."
03:54Because well, we'll get into the details of how this is working later on, but
03:57we're actually specifying the origin of the documents that we're sending and
04:02receiving messages from, so that we can't easily be spoofed.
04:06So I'll just change that back.
04:07What you're going to need to do is every time we bring up one of these examples,
04:12you're going to need to come in here in both of these documents you're going to
04:14need to change these variables to match the origin and the URLs that you're
04:20actually using for your documents.
04:22These will not work on your servers if you've got my URLs in here.
04:26And so in the document that goes in the outer window, in the One document--and it
04:31is pretty much always going to be on the same line numbers, 35 and 36--you're
04:35going to change the origin for Two and URL for Two.
04:38And then likewise, for the Two document, you'll see that there is an origin
04:44around line number 21.
04:45The line numbers might move a little bit here and there, but for the most part
04:48they're going to be very close or exactly the same throughout the course.
04:53So we'll be using this very simple example--I'll reload it here
04:56to get ride of the error message-- throughout this course to demonstrate the various
05:01techniques that we're using to make this work.
05:03And you can see that it's pretty simple in implement, and we'll be looking at
05:06more details as we go through the course.
Collapse this transcript
2. Event Listeners
Registering a listener
00:00The first step to implementing HTML5 messaging is to register a listener.
00:05This is done with the addEventListener method of the object you want to listen to.
00:09So what I have here is a working copy of listener-one-start.html and working
00:16copy of listener-two-start.html.
00:19I have named them both -working. And these are in the Chap02 folder of the
00:25exercise files, and I've loaded them up on my server so that we can test them there.
00:30And the first thing that I need to do is I need to come down here to lines 35
00:35and 36 and make sure that these match.
00:38So I'm in listener-one-working, and so I need the origin for the listener-two, and
00:45I need the URL for listener-two.
00:47Now the origin is just this. It's the protocol :// and the domain name and a
00:55port, if you're using one and probably not--that's very rarely done.
01:00The URL, in this case I need to change the word start over here to be working,
01:05so that it loads up the right version of the file. And I just pressed Save and
01:09you saw a little dialog box come up while it saved.
01:12I'm actually editing directly on the server.
01:15My editor will do that over SFTP, and I strongly recommend that you have an
01:19editor that does that.
01:20I'm using TextWrangler on a Mac here. At home I use BBEdit, which is the pay-for-
01:24it version of TextWrangler. TextWrangler is free.
01:27And if you're on a PC you can use Notepad++, which has that feature as well.
01:32Now if you don't change this, the danger is that you'll load up a different
01:35version of the same file and it will look like it's working, but you will
01:38make changes to that file and nothing changes on the screen, and you end up
01:42pulling your hair out.
01:43So I strongly recommend that you start each one of these lessons by making sure
01:48that you have these two things correct in both of the files.
01:51So this is in the -one file. And if I bring up the -two file, come down here to
01:57line 21, I'll see the same thing.
01:59This just has the origin; it doesn't actually need the URL of the -one file. And
02:05so it's got the originOne, and you want to make sure that that matches the
02:08origin that you're using.
02:11So let's just take a quick page-through of these files so that those who are typing
02:16along at home can do so.
02:26So that's listener-one-working.html, and this is listener-two-working.html. These
02:34of course are copies of the -start files.
02:37I strongly recommend you work with copies, that you don't work with the -done
02:41files, that you just start with the -start files and work with copies. And that way
02:47if you get stuck or lost, you can make a fresh copy and work from there. All right!
02:54So now we got our files copied, our files typed in, and we're going to get to work.
02:59The first thing we want to do in implementing a listener is to write the
03:03function that's going to handle the message event, and that function is going to
03:07be called handleMessage. And it gets an event object as its sole parameter, and
03:18the first thing that it does is it tests the origin.
03:20The event object has an origin member, so it says if (event.origin ==
03:26originTwo). And you notice originTwo up here has that string in it, the origin
03:35of the -two document.
03:37And I'm just going to go ahead and write the else right now, because this is a
03:41condition that we want to be concerned with.
03:44If the origin does not match, you want to do something other than actually use
03:50that data, and so I'm just going to display an error message.
03:52I am going to call my display error function, which you can find down
03:56below in the Utilities section.
03:59My error message will be informative. You don't necessarily want to do this in
04:02production, be informative, you might want to do something even nastier in
04:06production. But I'm just going to say, "message from untrusted origin," and I'm going
04:14to say what that untrusted origin is.
04:18So we can test it, and we can play around with it, and we can know exactly what's going on.
04:22Now the next thing I want to do is I want to test if I have a windowTwo object.
04:27If I don't, I'm going to grab it from the source.
04:29So I'm going to say, if not windowTwo. And you notice that windowTwo up here is
04:36defined as null, and so if it's still null, I'm going to assign it from the
04:42event. windowTwo = event.source.
04:48So the source member of the event object has that. It's actually a window
04:52proxy, but it works just like the window object, and so you don't even need to know that it's not.
04:56Now I'm going to log a message. I have this lovely little log method that
05:00displays those log messages on the screen. And I'm going to say message from
05:04origin, and I'm going to give the event.origin.
05:11You can see what that looks like. And then I'm going to log the data. And that's
05:21our handleMessage function.
05:24Now all I need to do is register it. And I come down here into init, and you
05:27remember that init gets assigned, it gets called, because it's assigned to the
05:32onload handler for the whole window.
05:34So once the page has completely loaded, then we call init.
05:39So the first thing I'm going to do in init is I'm going to add the
05:41eventListener, window.addEventListener, and it's for the message event, and it's going
05:50to called the handleMessage function. And then it gets this other parameter, which
05:56is false, which has to do with the way that messages propagate in the DOM, and
06:01it's always going to be false.
06:04So I'll go ahead and I'll save this. I'm just pressing Command+S here on
06:07the Mac. And then we can over to the listener-two-working, and we're going to do
06:13the same kind of stuff.
06:14I am going to come down here and make sure that our origin is correct there on
06:17line 21, and then I'm going to go ahead and create a handleMessage function. And
06:30actually, if you want to, because laziness is a virtue, I will just copy and
06:35paste this from the other one and just edit it.
06:39So our origin is going to be originOne.
06:44We don't need to test for windowTwo or even for windowOne, because we're not
06:47sending messages back--at least not from this function. And the rest of this
06:51is exactly the same.
06:53Then we come down here into the init function and we add our eventListener. And
07:01actually, this isn't used yet. We can go ahead and delete that line.
07:05So I'm saving the file and we have now registered our listeners.
07:10When we run this in the browser, listener-one-working, we see that it's running properly.
07:16It's not really sending any messages yet-- we'll get to that in the next movie--
07:20but you can see for now that it's really a straightforward process to register a
07:23listener: you just create the message handler and then you pass the function
07:28reference to addEventListener.
07:29In the next movie, we'll go ahead and send some messages back and forth.
Collapse this transcript
Sending messages to a listener
00:00Sending messages to a listener is simply a matter of calling the postMessage
00:04method on the target window object.
00:07So here I have a working copy of sender-one-start, and I named it
00:13sender-one-working.html, and this is in the Chap02 folder of the exercise files
00:19on my server. And over here I have sender-two-working.html, which is a working
00:26copy of sender-two-start.html and I'm also editing that on my server.
00:33So the first thing I'm going to do is I'm going to page through this, for those
00:36of you who are typing it in all.
00:41This is actually the place where we left off in the last exercise, so if you did
00:46the last exercise, you already have this file.
00:53So that's the sender-one, and this is sender-two.
01:14I'm just noticing that this time function goes off the end of the screen there
01:17just a little bit. So you can see what that is. It's just got one little
01:22character off the end of the screen there.
01:25So now the next thing we want to do is we want to make sure that we have these
01:29two variable correct, the origin and the URL.
01:32So in sender-one on line 35 and 36, you want to make sure that these match
01:38exactly. And you notice here it says listener-two-working, because that's left
01:42over from the last time, so I'm going to type in here sender-two-working. And
01:49the rest of this is correct, so I'm going to press Command+S to save and then
01:53look over at sender-two and do the same thing here on line 21. You just want to
01:59make sure that that is the origin for your opposite file.
02:05So while we're in sender-two, we're going to ahead--because sender-two is the
02:08first one that actually gets ready to send a message, because you remember,
02:13sender-one loads up sender-two, and so sender-one doesn't actually have a window
02:19object for sender-two until sender-two sends it a message.
02:22The first thing that sender-two has to do is it needs to send a message to
02:26sender-one to let it know that it finished loading.
02:29So I'm going to come down here in init. I'm actually going to start with a
02:33comment and say, "send a message to the parent to let it know that windowTwo
02:41has finished loading."
02:46And so I'm going to make a local copy of variable for windowOne because I'm not
02:52actually going to use this outside of here; otherwise, I could make it global.
02:58There wouldn't be any harm in it. And I'm going to assign it to that parent.
03:03Because we have a parent object already--this got loaded up by the parent--so
03:07we can just load parent and get that window object as easily as that. And then
03:11I can say windowOne.postMessage--it's really that simple--and give it the
03:18message and originOne. And so in the message here I'm just going to say, "this is from windowTwo!"
03:30And then we'll log it that we've done something.
03:33You know when I'm developing or experimenting or learning about something, I like
03:37to do a lot of logging, and it tells me exactly what's going on and in what
03:41sequence, and it helps me to keep track of what I'm doing and what I'm learning.
03:46"message sent to windowOne."
03:48All right, so I'm going to press Command+S to save this on the Mac, and we're
03:53going to go ahead and run it.
03:54Now we've only changed sender-two. We have not changed sender-one, except to
03:58make it load up the right thing, but I'm still going to start with loading up
04:03sender-one-working, because that loads the frame for sender-two.
04:06So I'm going to click on sender-one-working, and there we go.
04:11The outer one is sender-one, and the inner one is sender-two. And you notice here
04:16it says, "message sent to sender-one."
04:18As soon as it loads up, it sends a message to sender-one, and sender-one has
04:22this message from origin, and there is the origin of two.3sn.net, and this is from windowTwo.
04:29So windowOne loads up windowTwo. windowTwo loads up, and the first thing it
04:34does is it sends a message back to windowOne to let it know where it is, and
04:37now windowOne actually has a window object for windowTwo. It didn't have that before.
04:43So now we can go back here into windowOne, sender-one-working.html, and here on
04:50our handleMessage function, you see where we have the message from origin,
04:54and that's this message right here. And there is the origin where it came from, two.3sn.net.
05:00So that's working. And we log the event data, and that's this message here,
05:05"this is from windowTwo."
05:07And so now what we can do, you see this message here that says, "if not
05:10windowTwo, windowTwo = event.source," so we did not have a windowTwo before--
05:15remember, it's initialized to null--and so now we have it, because event.source
05:19gives us that windowTwo object.
05:22So now we can just come down here, we can say windowTwo.postMessage (this is from windowOne! and originTwo).
05:35You have to give it the origin of the object that you're sending it to. And then
05:41we'll log a message, and we'll save that with Command+S. Now we're going to go
05:51ahead and we're going to send a message back to windowTwo. So I'm going to press
05:55reload up here, and there we have it, "message send back to windowTwo."
06:01And then windowTwo has a message from origin, and there's the one.3sn.net, and
06:06the message itself, "this is from windowOne."
06:08So now we're successfully sending messages from windowTwo to windowOne and then
06:12back from windowOne to windowTwo.
06:16We'll take a look at a more interactive example later in the course.
Collapse this transcript
Handling errors
00:00There are few different types of errors you'll be concerned with in your HTML5
00:03messaging application.
00:05Fortunately, most of these can be handled in the same way.
00:09Here we have a working copy of errors- one start.html and errors-two start.html.
00:13I've made working copies on my server, and I'm editing directly on my server.
00:19We'll just take a moment now and page through these for the benefit of those of
00:22you who need that. And here's errors-two.
00:47Now the first thing we want to do is we want to go into each of these files and
00:51edit our constants, make sure those are set correctly.
00:54Here we have originTwo, which is set to the hostname of the server with working
00:59two on it, and URL two, which is the complete URL to errors-two-working.html. And
01:07we'll go into errors-two and check the same thing.
01:11And here's the line that you want be concerned with, and make sure that that has
01:15the hostname for your originOne server.
01:20And now coming back here into errors-one, we need to add the event handler
01:26for the error function.
01:28You notice down here we have a function called windowErrorHandler, and this is
01:32the error handler, actually for both of these. We have the same function in
01:36both of these files.
01:37And so that's called windowErrorHandlers. I'm just going to put that in my copy
01:40buffer and come up here into the init function and add a handler for that.
01:45Now in this case I'm going to use an IDL handler, so I'm going to say
01:50window.onerror = and the name of that function with a semicolon.
01:56I am going to save that.
01:58The reason I'm using an IDL listener instead of an addEventListener is that
02:03support for error handlers with addEventListeners is inconsistent amongst
02:07the different browsers.
02:09And even here on Firefox it's not completely implemented.
02:13So this works well with the IDL listener and it does not work well with
02:16the addEventListener.
02:18So I'm just going to make copy of this line, and I am going to put exactly this
02:21same line into errors-two-working.html. I'll scroll down here to the init function
02:28and paste it in right there and press Save.
02:32So now we have the event listener installed for onerror in both of our files, and
02:38I am going to come over here to the browser and load this up.
02:40So I'm going to load up error-one- working.html on my server, and there you see
02:45the messages going back and forth exactly how we expect them to.
02:49And now we'll just start introducing some errors and see how that works.
02:52It's a really good idea to play around with errors when you're building error
02:56handlers, so that you know what to expect.
03:00So the first thing we'll do is we'll change our origin from two to three. So
03:05this is in errors-one-working.
03:07And so when we come in here and handle message events, the first thing we do is
03:12we check if the event origin is equal to this constant and if not, we display
03:17this error message here.
03:18I am going to come back over here into the browser and reload this. And you
03:22notice we get the message, "message from untrusted origin" and it lists the origin
03:27where the message came from, which is different than what it was expecting,
03:30because here it's expecting three instead of two.
03:34So this is a message that we're sending out ourselves from this test, and so
03:38it's not really using the onerror handler. Let's go ahead and use the onerror handler now.
03:44So I'm going to change that back, and I am going to come down here and put
03:48something nonsensical in this postMessage. I'm just going to say foo. That's not a
03:53full URL and so if for some reason you had an error like that,
03:58we'll go back into the browser and we'll bring that error up and you see we have
04:02an uncaught exception.
04:04So, this is our error handler working.
04:07You notice when we come down here to our ErrorHandler, it prints the message and
04:11the file name and the line number.
04:13And here we have the uncaught exception message and the file name and the
04:20line number right there.
04:21So this gives us some idea of what the problem is: an invalid or illegal string
04:26was specified on line 44. And if we come back up here to line 44, we
04:32can deduce what the problem is. So I'm just going to put that back to our
04:36constant, and let's go make another error.
04:38If I come down here to line 54 and I actually call a function that's not
04:43defined--I just misspelled this function here instead of log its xlog, and so
04:48I'll press Save and we'll come back over here to the browser and we'll load that up.
04:52And we see it says xlog is not defined, and it doesn't run the rest of the
04:56script; it just stops right there. xlog is not defined, gives us the file name and
05:01the line number on line 54.
05:03So that's exactly what we expect.
05:05On the other hand, if we introduce some error here by misspelling the word
05:09function, this will not catch the error.
05:11Why? Because this is the function where the error handler is actually installed.
05:18And so if we never get to that line, we're not going to get our error handler at all.
05:22So if I save this and bring this up and run it, you'll see that I get no
05:26error message at all.
05:27On the other hand, I can come up here to Tools > Web Developer. This is in the
05:32Firefox browser. You have something like this in most of the browsers.
05:35Now bring up the console and if I press Reload, you'll notice that I actually
05:41get an error message. It's a typical cascading interpreter error message that
05:46doesn't really tell you what the problem is, but it gives you an idea of where to look.
05:50It says it's missing a semicolon
05:51around line 51. And in fact what it is, is it's got an unrecognized keyword. And
05:57so we take out that x, and we save it, and we come back in here, and we reload, and
06:02we see that everything runs as we expected to.
06:04And I can take down that web developer console.
06:08And so now that we have our error handler working, we have a complete set of
06:11tools for HTML5 messaging, and we can look at a more interactive example in
06:16the next chapter.
Collapse this transcript
3. Cross-Document Messaging
An interactive example
00:00Now let's take a look at a more interactive example of cross-origin messaging.
00:04This is a little chat app, and while it may not be terribly useful to chat
00:09between two windows on a single desktop, it does give us an opportunity to
00:13explore some of the subtleties of the messaging interface.
00:16So this application works much like the ones that we've seen so far; in fact it
00:20uses a lot of the same code.
00:22The first thing that it does is it loads up the second window inside a frame, and
00:27then the second window inside a frame sends a message back to the first window
00:31to tell it that it's loaded.
00:33So you'll see in the first window, which is the outer one, we have this log "this
00:37is windowOne" and its host, one.3sn.net. And windowTwo is on two.3sn.net so they
00:44are in different origins.
00:46And then once windowTwo gets loaded, it sends this message to windowOne that
00:50says, "windowTwo is loaded."
00:52And the purpose of that is so that windowOne now has a handle to windowTwo's
00:58window object or rather, a window proxy object that works just like its window object.
01:02You'll also notice that it says info, and the reason for that is that we're
01:07actually sending some structured data that categorizes the different types of messages.
01:11And we have two different types of messages: we have info message and we
01:14have chat messages.
01:15So when I come up here and I type a message, a chat message, you'll see that
01:21that message shows up over here without saying info in front of it.
01:24And if I send one over here, you see that it comes up over here without it
01:31saying info in front of it.
01:33And the reason for that is that there are actually two different categories of
01:36messages that are being sent, and it's being sent as structured data with JSON.
01:41And the reason we're using JSON is because this application worked just fine with
01:46the structured data except on the Internet Explorer.
01:49And in order to for it to work on Internet Explorer, we had to use JSON, because
01:53Internet Explorer is only sending strings in its data payload.
01:57So now that we've seen how the app works, in the next movie we'll take a look at
02:01the code and see how it's implemented.
Collapse this transcript
Exploring the example code
00:00So this is our little chat application, and you can see that I can type in a
00:04message here, "hi there," and it comes up over there. And I can type in a message
00:09here and it says, "hi back," and that one comes up over here. And these are in two
00:15different domains, which means that they're in two different origins for the
00:18purposes of the same-origin policy.
00:22So let's take a look at how this works and how this is implemented.
00:24Here we have chat-one.html, and this is the one that's running on one.3sn.net,
00:30and here we have chat-two.html, which is running on two.3sn.net.
00:36So before we move forward, let's just take a quick browse through it for the
00:39people that are typing along with us.
00:57So that was chat-one.html, and now we'll look at chat-two.html.
01:19And the time-string gets cut off there just a little bit. There it is. And there we have it.
01:30So the first thing you want to do is you want to come down here in both of these
01:35and make sure that your URLs and origin strings are correct for your server.
01:41These are correct for my server here on 36 and 37 in the chat-one, and in
01:46chat-two it's right there on line 24.
01:48So you want to make sure that those are correct for your server.
01:52So there are a couple of things that are different here and that make this work.
01:58First of course we have the init function, which gets called by onload, way
02:03down there on line 131.
02:06And in chat-one really all its doing is setting up the event handlers, loading
02:12the frame, and selecting the chat text box.
02:17And so if we come down here into the HTML, you notice that we just have this
02:22little form with an onSubmit, so it doesn't have a Submit button.
02:25All you do is press Enter on the one field. And it's got this one text field, and
02:30it is called chatText.
02:32So up here in the init function you see it gets that element using the little
02:37element shortcut that I've got down here in my Utilities.
02:40It gets that element and it calls select on it, and that's what gives it, when we
02:45load this page up, you notice the first thing it does is it selects whatever
02:49text is in that box and it puts the cursor there.
02:53Other than that, it's just waiting for a message to come in. And when a message
02:56does come in, it calls this handleMessage event handler, and you'll notice that
03:02it calls JSON.parse on the event data.
03:06And the reason for this is that whenever we send a message--notice here is our
03:10sendChat function--when we send a message we call sendObject, and sendObject
03:15actually takes that message and it calls stringify on the JSON, so that it takes
03:20that message it, converts it to JSON, and then it post it as a text string.
03:25And the reason for this of course is so that it will work in Internet Explorer.
03:29So that adds a little bit of complexity.
03:30chat-two is almost exactly the same.
03:36The main difference being in the init. Because when the init gets called, it can
03:41grab that parent object and call it windowOne, and it calls sendObject again so
03:49that it gets JSON-stringified to send that windowTwo loaded message we saw over
03:54here info windowTwo loaded.
03:57And so all of the messages are being sent as structured data. So this message
04:02is being sent as an info-type message, and the chat messages are being sent as
04:07chat-type messages.
04:09And all of that gets stringified in sendObject.
04:15So really, those are the only significant differences between this and the
04:19applications that we've seen earlier, and so it makes it really simple to send
04:27arbitrary data back and forth between two windows in different origins.
04:35So you can see that the HTML5 messaging API is simple enough that it can get out
04:41of your way and allow you to get creative with your applications.
04:44Obviously this is a contrived application designed to demonstrate the features
04:48of the interface, but hopefully you can see how easy it is to implement cross-
04:52origin scripting with the HTML5 messaging API, and now you can use it in your
04:58own real-world applications.
Collapse this transcript
Conclusion
Goodbye
00:00In this course my goal was to give you a good understanding of the HTML5
00:04messaging application programming interface.
00:07I've covered how the API works, how to setup the event handlers, how to send and
00:11receive data, and how to handle errors in your messaging applications.
00:15Using these features, you should be able to implement cross-origin scripting for
00:19your own applications.
00:21As with most of the HTML5 application technologies, the specifications for the
00:25HTML5 messaging API remains in flux.
00:29I suggest that you keep up with these changes in order to make sure that your
00:33code works with current and future browsers.
00:36And be sure to check out the other HTML5 titles, as well as the excellent
00:40JavaScript Essential Training with Simon Allardice here on the lynda.com
00:45Online Training Library.
00:46As always, feel free to use my working examples as a starting point for your own
00:50applications, and I look forward to seeing what you do with the HTML5 messaging
00:55API in your own projects.
Collapse this transcript


Suggested courses to watch next:

HTML5: Structure, Syntax, and Semantics (4h 34m)
James Williamson

HTML5: Geolocation in Depth (34m 19s)
Bill Weinman


HTML5: Web Forms in Depth (1h 58m)
Joe Marini


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 98,718 instructional videos.

start free trial learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 1,899 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.


site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked