Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2008-403
$eventId
ID of event: wwdc2008
$eventContentId
ID of session without event part: 403
$eventShortId
Shortened ID of event: wwdc08
$year
Year of session: 2008
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2008] [Session 403] Using Advan...

WWDC08 • Session 403

Using Advanced AJAX Technologies in Safari

Essentials • 51:04

Many modern web applications gather data from multiple sources and share that information with users. Discover new features in Safari and WebKit that enable secure and efficient data sharing across multiple domains. Learn to leverage other advanced web technologies such as XMLHttpRequest, postMessage, and querySelector to improve a web framework, add features to a web application, or invent the next great mashup.

Speakers: Geoff Garen, Kevin McCullough

Unlisted on Apple Developer site

Downloads from Apple

SD Video (439.3 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning. Welcome to the AJAX session. I'm Geoff Garen. I'm an engineer on the Safari and WebKit team. I hope that some of you at least had a chance to come to the WebKit party Tuesday night. Anybody? For those of you who came, I hope that your hangovers the next morning were mild. So what is AJAX? Well, in the beginning, God, as we all know, created the internet.

And the Internet was a web browser pulling data from a server and pushing it out to the user. Pretty simple. But soon enough, there were enough servers and enough users that we started to think of the Internet as an information superhighway. And I would call this the first technology revolution on the Internet. For its time, this was amazing. You could be sitting in your basement, probably in your underwear, and you could access a document located in Berkeley, California, or in Cambridge, Massachusetts, or London, England, or anywhere else all over the world.

But there was an important limitation to this version of the internet. The information superhighway was a one-way street. You could access a document anywhere in the world, go to any web page, but once you were there, you were kind of stuck. You couldn't interact with it the way you could interact with the rest of the applications on your system.

What you could do is you could click a link that would take you to another web page, and from there you could click another link to another web page, and so you could go from place to place to place on the Internet. And that experience of going places on the Internet was so fundamental to the Internet in its time that Microsoft even coined the trademark, where do you want to go today? Geoff Garen, Kevin McCullough Does anybody remember that? Microsoft's technology luminary on the internet? So eventually we all realized we weren't really happy with that situation.

It wasn't really as interesting as the desktop experience, and I think that's what brought about the second technology revolution on the internet, AJAX. Standard techniques on the client side with JavaScript to update a user interface in response to user behavior and simultaneously through asynchronous XMLHttpRequest to fetch new data from the server as necessary.

So here's an example of one of the first AJAX applications, and still I think one of the best. This is Google Maps, and I can go to maps.google.com and do a search for San Francisco, California. And once I've done that, I have all kinds of user interface widgets. I can slide a slider or click a button or drag the map, or I can even use my mouse wheel in order to interact with this map.

So I can zoom down here to the Moscone Center, and I can zoom in a little further through Street View to see the front door we all came through this morning. This is pretty great technology. I think I can zoom one more level all the way into the conference itself. And here we have an Apple engineer hard at work in the lab.

But now, the kids these days, with their hippin' and their hoppin' and their bippin' and their boppin' and their remixing and their sampling, they love to take content that's already out there on the internet and mash it all up together into a new experience that's greater than the sum of its parts.

And so we call this mashups, and I think it's the beginning of the third technology revolution on the internet. And I say beginning because I think that there are some critical limitations in the way that mashups work today and the APIs that they rely on that have really held back mashups from reaching their full potential.

Let me give you some examples. Here's Zillow.com, and it has that same AJAX map interface that I showed you earlier, but Zillow has mashed up into the map their own real estate and housing information. So as I look at an area on the map, I can see homes for sale and their prices, and also recently sold homes and things like that. Simultaneously, on the left side of this web page, I have an ad for Lowe's Home Improvement, which is a document that came from another part of the Internet. The assumption being that, you know, if I'm looking for a home, I'm probably interested in home improvement.

The limitation here is that the Lowe's ad doesn't know what the map is looking at. If it did, it could show me something a lot more relevant. For example, locations of Lowe's stores in the area. Or it could even go out and fetch me Yelp reviews of Lowe's stores in that area, assuming that the reviews are positive. Maybe there could be some filtering. So here's another example.

This is a fun one. This is Yahoo Pipes, which is an application for making your own mashups and then publishing them. And here I've made the I Can Has Cheeseburger pipe, which will go out and search Flickr for photos that match I Can Has Cheeseburger and then display the results in a Yahoo web page. And this is what that looks like.

So once again, this is great technology. Obviously, we need to accelerate the speed at which kittens proliferate on the internet. But there are some critical limitations here as well. The main limitation being that I have to do all my communication through the Yahoo servers. So there's an extra round trip for every single resource that I request, basically making my application twice as slow as it needs to be.

And also, I can only make requests for things that are statically supported by programs written on the Yahoo servers. So I can't make arbitrary requests. And if you're maintaining mashups like this on your own server-side mashups, then you have to write a lot of glue code on the server-side in order to make this happen.

So that's really what my presentation today is about. It's about the third technology revolution on the internet, mashups. And critically, it's about new standards that we've implemented in Safari to release mashups from their existing limitations and allow them to fulfill their full potential in your websites and web applications and desktop applications that rely on web content.

I'll cover three categories of APIs. First, I'm going to cover APIs for document manipulation. When you get new data over the server, these are the APIs that can initialize your web page or update parts of its user interface as necessary. And mostly, these are things that have been around in libraries for quite some time now, and now they've been standardized and implemented natively in the browser, making them easier and quite a bit faster. Then I'll move on to message passing. This is a new API that allows documents on the client side to communicate and interact with one another, even though they don't completely trust each other and they need security in an environment of mutual suspicion.

And finally, I'll cover Access Control, a new standard implemented in Safari that allows your documents on the client side to access not just your own servers, but any other server they need access to on the Internet. And I think that these three APIs together create a compelling story for the future of the Internet where in very simple and efficient ways you can update your document either through communication with other documents on the client side or as each document communicates with any server it needs access to on the Internet.

And I think that these together can maybe take that Web 2.0 plus and kick it up a notch, maybe even to Web 3.0. And the reason I would call it that is that here we have internet technology not just trying to catch up to the desktop anymore, but maybe even surpassing it, doing things that you can't really do with a static bucket of bits on a hard drive.

So let me get started with document manipulation. Here we have one of my favorite blogs, the Death Bacon Kket. I like this blog because it tells me what I'm going to have for dinner. And as you're probably familiar, there are critical portions of this website that if I were going to reference them in my markup, there are pretty standard ways to do that. So for example, I have a masthead, which is a div with the ID attribute masthead.

And in CSS, to style that masthead, I just need to use the number sign followed by its ID, and bingo, I can set a font or anything else I need. In JavaScript, we have the same capability. You can call getElementById to grab that masthead and maybe programmatically insert text or do anything else that you need to.

So this is a pretty simple API. It's been around forever. It's quite fast. But it is limited, and the limitation is that it doesn't scale very well. I can't really set an ID on every single element in my page, and sometimes I need to reference more than one element at once.

So scaling up a little bit, we also have the ability to reference elements by their tag names. So here I've referenced all the anchor tags in the DeathBake and KCAT. In CSS, I just need to supply that A, the anchor tag, and then I can style them, turn them all red, something like that. In JavaScript, I can call getElements by tag name and supply that anchor tag, and bingo, now I can add dynamic behaviors to them as well.

But there's one other element on this page I want to talk about, and here we have three portions of the page that are all picture frames. They look like picture frames. I need them styled that way. And that's how I think of them when I'm interacting with this page and composing it.

And in CSS, I can reference them because I've given them all the class name, picture frame. And so I just use that dot picture frame notation, and I can style all my picture frames and add the border that I need. But you'll notice that the JavaScript box is empty. There's no way to grab all the picture frames on the site in order to work with them.

So new in Safari 3.1, we've implemented that ability in JavaScript, and it's called GetElementsByClassName. This is a new standard as well. It's pretty simple. It takes a space-separated list of class names so you can supply one class or many, and it returns to you a live node list of all the elements that have that class name. So this is a node list that will update as you update your DOM.

Here's an example where I've grabbed all the posts from the DeathBake in KCAT by calling getElementsByClassName and passing in the class post. So you can start to see how there's a structure in my web page that I can reference because it's already there for CSS, but it doesn't necessarily conform just to tag names or IDs. Here's an example of using more than one class name. So I'm trying to access just the new posts. So I pass posts separated by a space from new, and I get all the elements that have both of those class names.

One interesting use of Access by Class Name is microformats. Microformats are mini standards for ways to compose the data in your documents in a standard way so that different tools can read them and access them. So if your web page conforms to the Hcard microformat, you have data in your web page that's contact information. And if you need to get at all the contacts in your web page, all you do is you call getElementsByClassName and you pass the Hcard class name and bingo, that's all of the contacts in your page.

If you were at the Rich User Interface in Safari session, you know that there's a new API, a standard API in Safari for adding accessibility annotations to your page, and that's called ARIA. And basically you set attributes on elements that annotate what kind of element they are. So if you have images on your page, for example, that function as buttons, you need to set a role attribute on those images and say this is a button.

So here's a really simple way to do that when you initialize your web page. You get elements by class name to grab all the buttons on your page, and then you iterate through them, setting the attribute role to button. And all of a sudden, you have this rich user interface in accessibility land as well.

We did some ad hoc performance testing because we love performance testing, and we discovered that accessing elements by class name in Safari is a full 30 times faster than the fastest alternative, which is XPath, a fairly complicated XML querying language. And XPath is itself, I don't know, maybe between 3 and 10 times faster than doing this manually through JavaScript and DOM. So at the limit, we're talking about a speedup of between 100 and 300x.

Think about that for a minute. That's like when Steve Jobs came on stage to announce the new Intel machines, the switch from PowerPC, and he said, 5x faster. Now imagine that immediately after that he said, but there's one more thing, and he threw that computer in the garbage, and he brought out a new computer, and he said, 5x faster again. Then he threw out that computer, and he said, wait, there's one additional thing, and he brought out a new computer. That's what you get here.

So I think if you haven't been doing this kind of dynamic content before, you should consider it because the performance really is there to support it on the client side. And if you have been doing it already, either through libraries or through your own code, you're going to get a magic speedup in Safari.

So as the big Lebowski likes to say, you've got to feed the monkey. And I've decided to monetize this web page by adding Flash ads all over it. I think they look great. I have on the left-hand side the Home Depot, because this is a pretty homey website. And on the right-hand side, Heineken, because nothing goes better with chocolate cake than Heineken. And I don't think they detract from the user experience at all. And I'm making a killing on these.

And so in CSS, if I want to style all the ads on my web page, I have this very complex and interesting and powerful selector language to reference different elements through different criteria. Here, I've selected all my ads through the following criteria. I want everything that has the class Movie, but I don't want all the movies on my page. I don't want to select the movie of chopping onions or anything like that.

And I also don't want the movies that are not plugins, so I want it to be an element that has the tag name Object. And finally, I want it to be a descendant of something that has the tag name Add. Or, I'm sorry, the class name Add. So that's how I know I have all the Flash ads on my website.

You'll notice once again that the JavaScript box is empty. So there's a new standard that we've implemented in Safari 3.1 called querySelector that allows me to do the exact same thing from JavaScript. It takes as its argument a CSS selector, and it returns the first element that matches that selector in document order.

So here's an example where I grab the first Flash ad on my website by calling querySelector and passing that same selector I showed you from CSS. Of course, what I really want is to get all of the ads on my site. So another new standard implemented in Safari 3.1 is querySelectorAll that does the exact same thing, but it gives me all the elements that match that selector, not just the first one.

So once again, it takes as its argument a CSS selector, and it returns a static node list. So this is not a node list that will update as layout and rendering change. The reason is that layout and rendering need to be wicked fast. So we give you a snapshot of what things look like at the time, and if you want to run this CSS selector again later to see if something has changed, you should just call querySelector again.

So here's an example of getting all the movies on my web page by calling querySelectorAll. One reason I might want to do this is because my evil Sith Lords have told me that they're not going to pay me unless all of their annoying ads start running the moment that the web page loads.

So here's a way I can do that. I make my selector to grab all my Flash ads. But once again, I don't want to accidentally start the onion chopping video or anything like that. Then I pass it to querySelectorAll, and I get a list of all the ads. And then I can run through the list calling startPlay to start all the Flash movies.

Now I'm sure that most of you will be more merciful to your users. And so you would probably use this technology for good and rather than evil. And you might have a link on your web page that says, OK, I've seen enough of your ads. Please pause them.

And that would look exactly the same way, except you would call stopPlay instead of start. So the lesson to take away here is that the browser is doing all of the heavy lifting now of selecting all the elements that you need to update. And all you need to do is write the code that actually adds the behavior you're interested in.

Once again, we did a little ad hoc performance testing, and we found that the Access by CSS selector in Safari 3.1 was a full 10 times faster than the fastest library implementation here. And, you know, it's not that these libraries are any slouches or anything like that. It's just that the engine is already computing a lot of this information for the sake of layout and rendering, and now we're just making that computation available to JavaScript. So we have a lot more power in the engine than libraries do with a lot less overhead. So if you're using one of these libraries already, they will automatically fall back and use the native implementation, and you'll just get a magic speedup.

If you're not using these libraries, then I encourage you to consider this a new tool in your arsenal for addressing your document. So we have a demo for you of Access by Class Name and CSS Selector, some of the things you can do with it. And for that, I'd like to invite to the stage Kevin McCullough.

Thank you, Geoff. I am Kevin McCullough, engineer on the Safari and WebKit team, and I'm going to show you a demo of what Geoff was just talking about. So let's bring up Safari here. And I've created a website that is a copy of our Surf and Safari blog.

On the right hand side, if you haven't seen the blog, please go to it, webkit.org/blog. On the right hand side, we have a list of links that are interesting to the blog. And down the center, we have a set of posts. And if I scroll down this page, on the right, you're going to see our archives that are listed by month and year. And you can click on any of one of those, and it will take you to that month in that year, and you can see all the posts there.

What this site is missing is a list of links that tell you what posts are on this page. So what I've set up is using getElementsByClassName. On the right hand side, I have a button. And using that button, it will generate a list of links for every post in the page that will take you to that post if you click on it. And it gets those posts by using getElementsByClassName because I happen to know that every post has the class name post. So let's do that right now.

So there's all the links. And I can take you to each or any of these links. Let's just pick one. And it scrolls partway down the page, and it finds the post that was on the page. So let's scroll back to the top. And let's look at the code for that.

This code is fairly simple. If you look at the top function, all I'm doing is getElement by className, and I give it the className post, which is this one here. I iterate over the list of links or list of elements that are returned. I create list items out of them, and then I append them to the unordered list. And if you read the next function, I do the exact same thing with querySelectorAll. But the querySelector is a little different.

I want to get all the posts, but I want all the images in all the posts. So what I want to do is find every image on the page, but I don't want every image on the page. I just want the images that are inside of the posts. So it uses, obviously, as Geoff told you, the CSS selector syntax, and it gets only images on the posts-- or in the posts.

So, for example, the Surf and Safari logo in the top left is not going to be found when I click this link. So let's do that now. And here's all the images in all the posts, and I can click on any one of those, and it'll bring up. There's our beloved Kate Hyatt, daughter of Dave. And let's click another one.

There she is again. So hopefully this shows you just how easy it is to use. If you're using a library already, you should be able to just use the exact same function. If not, it was obviously very simple to just generate all the elements that I was looking for using getElementsByClassName or CSSSelector syntax.

And now I'll turn you back over to Geoff. Ladies and gentlemen, Kate Hyatt and Kevin McCullough. So that was document manipulation. We showed you get elements by class name when you want to rely on the class-based structure of your document rather than tag names or IDs. And also, for the most powerful syntax available, query selector and querySelectorAll.

Now let's move on to the good stuff, the new stuff, message passing. As you may remember from grade school, life is a lot more fun when you can pass messages, when you can connect and interact with the people around you. And the same is the case on the Internet. It's more interesting when documents that you load can interact with one another. For example, what I described earlier, the Lowe's ad knowing what I'm looking at in the map so that it can give me tailored content.

So I guess what I'd really like on the client side is for all the documents I load into my web browser to be able to access one another so that they can do that kind of sharing and cooperation. But there's a problem. You see, on the internet, nobody knows that you're a dog.

Which is my way of saying that it's largely anonymous. You know, you don't -- when you click the first link in an RSS feed or on Digg, you don't really do a background check on the author of the page. You don't even know who the author of the page is, and you don't care. You just trust that the browser's going to display the page and, you know, not do anything bad.

Of course, the author of the page may not be a human or a dog. The author might be the Big Bad Wolf, a hacker or a phisher or some other attacker who wants to steal your private data in order to make bank transactions and send your account to Nigeria.

Try to save a prince in Nigeria? Buy a bedpost from Nigeria? So I want to give you some examples, two examples of the attacks that are possible in the web browser. This won't be a comprehensive discussion of security in the web browser, but it should be enough to give you a context for understanding message passing.

So in the first attack, the question is, what happens if documents can read from one another on the client side? So I have open in one window my bank account website. And because I got to check my ad revenue, I mean. And I have in the other window a hacker website that I accidentally stumbled upon.

So if documents on the client side can read from one another, you'll notice that my bank account has sensitive information in the website. It has my account number, my name, my address, enough information to be able to withdraw funds. So if they can read from one another, that hacker website can grab that data for itself. And now they're off to the races with my ad revenue. If this happens to your own website and the users of your site, then it can really cause you to fold.

So in the second example, you might say, OK, I'm not going to allow documents to read from one another. But what if I just allow them to write to one another so they can at least communicate? Well, there's a problem here, too, because you'll notice that the hacker has cleverly crafted a login field that exactly matches the look and feel of my bank website.

It has the same color scheme and borders and everything. And so if the hacker can write to a document on the client side, they can do this. And then all of a sudden, I think that my bank account is asking me for my name and password, and I type it in, and the hacker is once again off to the races.

Because of these dangers, the default browser security model simply prohibits access between any documents on the client side, with one exception. The exception is if both documents came from exactly the same origin, the assumption being that the origin isn't keeping secrets from itself. In order to determine origin, the browser applies a three-pronged test. The first prong is host. So, for example, if I load a document from apple.com and a document from google.com, they can't access one another because the host does not match.

The second prong is port number. So, for example, even if I load two documents, both from apple.com, they still can't access one another if I loaded one from port 80 and one from port 81. And finally, the third prong is Scheme. So once again, two documents from apple.com. If I load them into the browser, they still can't access one another if I loaded one through an HTTP URL and the other through an FTP URL.

Because of this browser security model, I think you basically see two kinds of mashups on the Internet today. And the first I'll call no access. What we have here is a web page with sensitive information from secure.com, and it wants to embed a banner ad. So what it does is it cuts out a portion of its page where that ad will render, and it sticks the ad there in an iframe, in a separate document.

This is pretty good for ads because it gives you a black box, but it's completely secure. But if the ad wants to use JavaScript to access the context surrounding it in order to see what's going on and customize itself, that's forbidden by the browser. So this model is pretty good because it's secure, but it's not very flexible.

And the second kind of mashup I'll call full access. Here on secure.com, I don't just want an ad anymore. I want to embed a full user interface widget. So it really needs access to the document around it in order to respond to events and interact and be a part of the correct layout and things like that.

So here the widget comes from widget.com. And in order to accomplish this interaction, I've embedded the widget directly into my document by loading a script from widget.com. In this full access mashup, the flexibility is great. Through JavaScript, the widget can access the whole document. But the danger here is that the user will be hacked.

If you include a script in this way, you really have to trust the script's author and hope that they're not going to conduct the kind of attack I showed you earlier, either by reading information or by writing information or by karate chopping and kicking your dog. And that's why I think we see basically two kinds of mashups today on the Internet. We see ads, and we also see mashups with highly trusted sources like mashups with Google and Microsoft Maps.

But I want to see more. I want to see all of the potential of the internet unleashed. And I think for this what we need is a kind of Goldilocks solution that is not no access, but at the same time it's not full access that leaves you insecure. Instead, it's kind of mediated access, and that's what we call message passing.

And here's what it looks like. So what we have here is two different documents on different domains. And so we've loaded them into different documents, and that way the browser applies all of its security measures. But at the same time, the documents, if they choose, can pass messages to one another, and then the recipient can decide what to do with that message. And that way, the message passer has no direct control and therefore cannot conduct attacks.

There are new standards implemented in the Safari 4 Developer Preview and also available in WebKit Nightly Builds that implement this technology. The first half is the ability to send a message to another document, and that's called postMessage in JavaScript. It takes as its argument a message string and a destination origin. Each of these arguments is important.

The message is a string because we don't want to let you send behavior to another document, like an object or a function. If you could do that, then you could conduct the second kind of attack I described, of inserting a login field or something like that. So you can only send primitive data a string, and it's up to the recipient to decide what to do with it.

You need to supply a destination origin because if you're sending sensitive information, you want to make sure that the browser verifies that it's going only to the right recipients. If you like, if you're not sending sensitive information, if you're just sending like the weather or where we're located on a map, you can supply a wildcard, star, and then anybody can receive the message if they like.

Finally, message passing through postMessage dispatches asynchronously, so the browser won't really tell you who's receiving your message or anything like that. Once again, for the sake of security, and if you want a kind of API where you can know that people have listened and received your messages, then they need to send a message back to you.

So here's an example of calling postMessage. This is kind of a hello world. I'm on secure.com. I've embedded a widget in another document. And I post a message, hello widget. And I specify I want this to go to a document from widget.com. I think that's where it's going. Please verify.

On the other side of the fence, you need to be able to listen for messages, and this is another new standard implemented in the Safari 4 developer preview in the latest WebKit Nightly Builds for receiving a message, and that's the message event. This is a message just like any other message in the DOM, like onClick or the load event, but this is the message event. And so here's an example of registering for that inside the widget. First, I call addEventListener, and I pass the string message to say I'm listening for the message event. And then I supply a function that should be called when that message is passed to me.

Importantly, the first thing I always do is I check and verify the origin of the sender. For example, if I'm going to respond to a message by coughing up sensitive information, I need to make sure that the person asking is the right person. Otherwise, a hacker can conduct an attack, even in this model.

The second thing that I do is I take the event data and I do my useful work with it. And the event data is the string that was sent to postMessage. So here it's helloWidget. And finally, I might even reply to the original sender so we can get two-way communication going. So this is a very powerful API for two-way communication. So we have a demo of some of the things you can do with message passing, and I'd like to invite back to the stage Kate Hyatt, Kevin McCullough.

Thank you, Geoff. So let's take a look at that. I've created yet another website. It's a fake social networking site. I call it My Planet WebKit. I've got my sufficiently awkward self-image off to the right. It has some third-party applications, and in the middle I have my list of friends. And apparently I need to get out more because they're all inanimate objects. Or me.

But let's say for this whole mashup and message passing scenario, I want to play this third party game. On the far left, you see there's a third party game button. I'm going to click that. And what it's going to do, it's going to open the game in a new window. And I'm doing that because I want to show you that these are on different domains.

So here's my game. And I'm going to use the Zoom feature to show you that-- This domain is myplanetwebkit.org, and this is game.thirdparty.com. Very creative. But you'll notice that the third party game has my friends in there. It has their images, it has their names, you can't see their names right now, but why is that? That's because I used post message when the game was opened, to tell it that these are the URLs of the images for these friends and it gave some context information so that when I click on one of these images, it's gonna use post message back to my social network to tell me that that friend was clicked on and increase their score in the game. So I'll give you an example. It's very simple, obviously.

Safari. Now, it has a click count of two. I clicked on it twice on a different domain. It sent the message over. But this isn't really what you want. You want this game embedded in your social network. So what I'm going to do is I've set up so that when I click on the top image of the game, it will embed itself inside the social network. So now it's in here. So now I can do the same thing. I can click. It's a really fun game. Safari is leading. Seafoam breaks ahead. Safari, Seafoam, who's going to -- oh! I play this all the time. So let's take a look at the code.

So here's the code in the social network. At the top, I add an event listener for the new message event. And then the next function under it is a post message handler. And it checks the origin to see that it came from the third party game. Just this line right here.

[Transcript missing]

If you notice this function, addToScore, it actually uses querySelector. Remember from previously, querySelector will get the first element that matches the CSS selector, and I am dynamically inserting the friend's name into the ID that I want to use to get which friend, because I know each friend has a score element, or an element with the score class name, but I don't know which one it is until the post message is actually received. So that's just another example of how to use querySelector. And with that, I'll turn you back over to Geoff.

Thanks, Kevin. So that was message passing. You use postMessage in order to send a message, and you call addEventListener and specify the message event in order to listen. Kevin showed you an example of two components that really trust one another. So you're sending names of friends and images and things like that. And that's one possible configuration.

But the important thing to take away here is that there's a wide range of configurations available to you. So sometimes, you're going to make data available to everybody, for example, the weather. And sometimes, you're going to decide not to make any data available, for example, a bank website. And there's a lot of in between there as well, depending on what you're trying to do.

Finally, let's cover access control. So here I have Google Maps, and it's great. I can interact with this map that it's showing me. But critically, it gets all of its data to update the map from maps.google.com. For example, you can't configure your server to store your data on data.google.com or anything like that because the browser will prohibit that access based on the origin test I described earlier.

That also means that you can't include multiple kinds of data from different sources. For example, when I'm looking at San Francisco, I'd really like to know about the weather here. But Google can't go out to weather.com or the National Observatory in order to get that data because the browser denies that access as well.

Another thing that would be great for Google to show me in San Francisco is maybe the news. I learned at the WebKit party that the New York Times is looking into making freely available a lot of its news stories for any websites that want to aggregate them. And this would have been really helpful for me when I lived in San Francisco because I used to go to this barbecue joint all the time and I would get directions to that through Google Maps.

And it turns out that that was really the number one place for people to be murdered in San Francisco. And maybe a couple news stories along that line as I was looking at part of that map would have been nice, you know. But don't worry, I survived. So like I said, the browser security model prohibits that access. And the reason is that the hosts don't match. Maps.google.com does not match data.google.com, nor does it match weather.com or any of those other servers you might want to access, newyorktimes.com, et cetera.

So in order to explain this, I'm going to give you another brief explanation of a potential attack. Once again, I have a hacker website accidentally opened in one window and my bank website in another window. And each of those is able to get access to its own server, hacker.com and bank.com.

But what happens now if the hacker website tries to make a request to my bank web server in order to directly initiate a funds transfer to Nigeria? What happens is on the internet, nobody knows you're a dog. They don't know who you are. It's largely anonymous. All that the bank sees is that there's a request coming from my web browser over my IP address during my session, which is maintained by cookies and other things.

So it looks like me. The hacker is masquerading as me when it makes this request to my bank. And that's why the browser prohibits it. Once again, what we need is a kind of Goldilocks solution that doesn't prohibit any access to any server. But at the same time, when you do access, it doesn't allow you to pretend to be me.

And so that's the new standard that we've implemented in Safari, and it's called access control. And basically, all it is is when you make one of these cross-site requests, we stamp it with the identity of the origin making the request. So here we've stamped the hacker onto the request. And I'm pretty sure the bank is going to say no to this one.

So this is a new standard we've implemented in the Safari 4 developer preview in the latest WebKit Nightly Builds. It's called Access Control, and it's a two-part stage, two-part handshake. The first part of the handshake is Safari's job, where it will send an extra request header in the HTTP requests you see on the server side. And that header is Access Control origin. That's what stamps the big bad wolf onto the connection. It says the origin of this request is whomever. So in the maps.google.com case, you'll see something like this when the request comes over the wire. Access Control origin of http maps.google.com.

Now, once you see a request on the server side like this, you have a wide range of options available to you. The first thing that you can do is you can do exactly what your servers do today. Ignore this extra header, respond to the request as normal, and then the browser will see that you have not participated in the handshake, and it will drop the request, and the connection will fail as it does today.

The second option you have is you can inspect the request, look at the origin, decide if you want to send back data, and maybe you decide no. In that case, just don't respond. And the browser will drop the request just like today. But if you do choose to respond and participate in the handshake, your server needs to send back another special header, the access control header.

And this header specifies who should get access to this response, the origin that should get access to this response. So the simplest-- I'm sorry. There's a fairly powerful syntax available to you where you can supply a whitelist and a blacklist through allow and exclude. The excludes are optional.

I'm not going to go deeply into the syntax because the simplest thing for you to do is just make the decision on the server side of whether you want to allow or deny, and then just copy and paste the URL that is the origin into your access control response.

So here the simplest thing to do, if weather.com wants to provide the weather to google.com, it can just respond by saying allow http maps.google.com. Or maybe Google hasn't paid its bill this year and weather.com wants to deny the data, in which case it can just not respond or respond without the special header and the connection will fail.

We have a demo of Access Control, and here's Kevin McCullough. Thanks again, Geoff. So in this fictitious world of social networks that I've created, I'm also assuming-- well, I'm going to assume, I'm going to assert-- that I've created an online dating site. And these are on two different domains. They're two different sites.

But I've made both of them, and I'd like to be able to share that information if the user opts into it. So if you'll notice on the left of my demo here, there's this red heart, and it says, to get my romance connection information. And that's going to make a cross-domain XML HTTP request to attempt to figure out who I've registered as my romantic interest. says, if that's too small, but it says, I'm not authorized. I haven't actually set that up yet. So let's go ahead and do that.

Open a new window, and I'm going to go to Romance Connection. I look pretty good. Again, I have kind of-- you can tell it's made by the same person. I've got my user information on the left. I've got people interested in the middle. Geoff? Let's go ahead and click reject on that one. So I have a couple of people interested in me, and on the right-hand side I have a button that says to share my romance connection information with my other site, myplanet.webkit.org. So I'm going to click on that.

And it says the Romance Connection is now sharing information with MyPlanet WebKit. And what that's done is behind the scenes registered that domain in a database. So when we look later at the header, you'll see that that gets added to the access control list. Then I'm going to have to go ahead and pick somebody who I'm interested in. And of course, who wouldn't pick Seafoam? And so I'm all set to go.

Except on the far left here in this black and white button, you might notice it says, show malicious gossip ad. I haven't embedded that because I want to pop it open again and show you that it's on a different domain. So just like the third party game, I'm going to do that.

And it opens kevingossip.com because in the world that I've set up, somebody is interested in gossip on me. And this is my demo, so you're all living in my fantasy world for today. Let's go ahead and look at that domain. And it is in fact kevin.gossip.com. I'm going to go ahead and embed that back into my Romance website. So now this is the scenario that Geoff was talking about where I've got a malicious ad that I'm logged in, so it's got my session cookies being sent when it makes an XMLHttpRequest.

And likewise, it's from my IP address. So for a lot of ways, it might seem like this is me making this request. This would probably happen on load, but I've set it up so when I click this button, it's going to attempt to make that request of my Romance Connections database. And it could not get my information, so that's great. So let's take a look at that code real quick.

So here's the code for the gossip website malicious ad. All it's doing is making an XMLHttpRequest. It does a get on romanceconnection.com database romancecgi and sends that request. If it fails, then it puts up this blocked message. If it succeeds, it's going to put up the accessed message. Now, the next piece of code I'm going to show you is the exact same function.

[Transcript missing]

And let's see what happens now. Hey, Seafoam. So this is our mashup. We have three different domains. We have a dating website, we have a social networking site, and we have a third-party game. They're all interacting with the main host site in ways that are opt-in and secure, and you have now data from all these different domains interacting with each other. And so with that, I'll turn you back over to Geoff.

Thanks, Kevin. So that was Access Control. It's a new handshake between the browser and the server. The browser will send an Access Control origin to stamp a connection with the origin making the request. And if the server wants to opt in, it can send an Access Control response to specify what origin can access the resulting data.

Just like with postMessage and the message event, Access Control allows a wide range of security configurations. Some servers will just say, "Yeah, sure, always. I don't care. It's the weather. It's the news." Some servers will just not participate at all, like my bank. I sure hope it doesn't participate in this handshake.

And some servers will have interesting intermediate configurations where they'll make some of the decisions or they'll ask the web browser to make the decision for them based on a list of allow and exclude. The point here is that it's really up to you to configure your servers as you like.

And I think that with both of these technologies, Access Control and message passing, what you'll start seeing is that different sources will start rolling out support for these technologies. For example, you know, the New York Times will start supporting with its own data servers, and other clients that you interact with might want to start configuring their ads to accommodate these APIs.

And more and more, you'll see support for this on the web. And if you're managing your own data and your own servers, you get that flexibility. - Yeah. - Yeah. You get that flexibility immediately. You can start putting data on whatever origin you like and configuring it, configuring your hosts how you like.

So that's all I have for you today. We covered document manipulation, APIs that have been in use sort of for a while now, but haven't been standardized. Now they are standardized. They're implemented in Safari. They're a lot easier to use and faster than before. We covered message passing, a technology for documents on the client side from different origins to securely communicate and mash up in an opt-in fashion.

And finally, access control, technology for a document on the client side to be able to access data from multiple servers if they choose to opt in. For more information on WebKit, the engine that powers Safari on iPhone and Macintosh and Windows, you can check out the WebKit open source project. We have a website and also an IRC channel.

Our technologies evangelists are Vicki Murley and Mark Malone, if you want to get in touch with them by email. We've got some great related sessions coming up later today. Utilizing offline data in Safari will teach you how to keep data that's specific to the user on the user's computer so they can continue using your application even when they're offline and so that when they're online, the application runs a little faster because it doesn't have to round trip to your network in order to get data that doesn't really need to be on your host. It's not as dynamic as the other stuff. We'll also cover debugging websites using our integrated developer tools, which is really essential if you're trying to do anything complex in Safari.