Plaxo OSCON 2006

29
Joseph Smarr - Cross-Site Ajax 1 Cross-Site Ajax Challenges and Techniques for Building Rich Web 2.0 Mashups Joseph Smarr Plaxo, Inc. [email protected]

description

Cross-Site Ajax Challenges and Techniques for Building Rich Web 2.0 Mashups

Transcript of Plaxo OSCON 2006

Page 1: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 1

Cross-Site AjaxChallenges and Techniques for Building Rich Web 2.0 Mashups

Joseph SmarrPlaxo, [email protected]

Page 2: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 2

The promise of mashups

• Create new experiences by combining components from different authors– Each site focuses on what it does best– Can wire up components in a novel way

• Google maps + Craigslist = HousingMaps

• Rich interaction often requires talking back and forth between components– House’s address lat / long map it

Page 3: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 3

Talking between web components

• Normal situation: all on the same web site– Communicate across frames / iframes / popups– Talk to server using AJAX (XMLHttpRequest)

• Problem: doesn’t work when components live at different domains (mashup situation)– Same-origin policy

• Can include JavaScript / images from another domain

• Can’t talk to frame / iframe popup or send an XHR

• Prevents snooping on secret web pages (e.g. intranet)

Page 4: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 4

•CAN include image / JavaScript / CSS from Domain B •CAN send XMLHttpRequest to Domain A •CAN talk to other frames / iframes / popups on Domain A

•CAN'T send XMLHttpRequest to Domain B •CAN'T talk to other frames / iframes / popups on Domain B

•CAN talk to other pages on Domain A

•CAN’T talk to any page on Domain A

Domain B

Image CSS JavaScript

XML / Web PageXHR

• So, how do mashups

communicate?

Page 5: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 5

How do mashups communicate?

• Often, they don’t (Google maps 1.0)– Single JavaScript all processing done locally

• Plotting lat/long or fetching image tiles is deterministic

– Can’t get any additional data (e.g. geo-coding)• Server-side proxy (HousingMaps, Flickr)

– Talk to your server it talks to the foreign site– Problem: bottleneck; barrier to mass deployment

Page 6: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 6

Server-side proxy

Web PageDomain A

ServerDomain A

ServerDomain B

Page 7: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 7

How do mashups communicate?

• Often, they don’t (Google maps 1.0)– Single JavaScript all processing done locally

• Plotting lat/long or fetching image tiles is deterministic

– Can’t get any additional data (e.g. geo-coding)• Server-side proxy (HousingMaps, Flickr)

– Talk to your server it talks to the foreign site– Problem: bottleneck; barrier to mass deployment

• Use flash for cross-domain communication– Can use crossdomain.xml to allow foreign sites– Yahoo maps uses this to do geo-coding

Page 8: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 8

Flash proxy

Web PageDomain A

ServerDomain B

Flash

crossdomain.xml

Page 9: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 9

How do mashups communicate?

• JSON-P (Script injection + callback)– Dynamically load JavaScript file with data

• Use DHTML to inject a <script> tag in the document

• Data is returned in JSON (JavaScript data format)

– Clever trick: specify callback function on URL• foreign-site.com/json-api.js?callback=myFunc

• Loads myFunc({ data: “hello” }); round-trip!

– Works well in practice, but some drawbacks• Limited control vs. XHR (just loads or doesn’t)

• API provider can return malicious code (e.g. steal cookies)

Page 10: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 10

JSON-P

Web PageDomain A

ServerDomain B

<script>

JSON + callback

Page 11: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 11

Using JSON-P in OO web apps

• Problem: callback function has to be global– Complex code maintains state / instances– Would like to handle callback with instance function on

instantiated object• Solution: bind the callback dynamically

– Create a globally-unique function name• Usually global prefix + auto-incremented counter

– Use a closure to call your function in object-scope– Send the global function name as callback

it calls your scoped function

Page 12: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 12

Dynamically binding a global callback

var cbName = 'cb' + JSON.callbackCounter++;

var cbFunc = function(jsonData) {

myFunc.call(myObj, jsonData); // call bound callback

};

JSON.callbacks[cbName] = cbFunc;

var globalCallbackName = ‘JSON.callbacks.’ + cbName

// url: '/json-api.js?callback=' + globalCallbackName;

• Used by dojo (ScriptSrcIO), Google Maps 2.5, Plaxo, etc.

Page 13: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 13

Summary of cross-site techniques so far

• No cross-site communication– Include partner’s JS file once (can’t talk again)

• Server-side proxy– Talk on the backend (bottleneck, barrier to adoption)

• Flash proxy– Talk through cross-domain flash (requires flash)

• JSON-P– Talk through script-injection with callback

(less control, partner could be malicious)

Page 14: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 14

What about updating another web page?

• Proxies / JSON-P let you access foreign data– But still can’t touch a foreign frame/iframe/popup

• Many potential mashups would like to interact with existing web pages– Auto-fill a form with your contact info– Highlight relevant search results / text snippets

• How can two sites that want to cooperate get around the same-origin policy?

Page 15: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 15

Page 16: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 16

What does the partner site have to do?•Add the button to your page

<a onclick="showPlaxoABChooser('textarea', '/cb.html'); return false"

href="#">

<img src="http://www.plaxo.com/images/abc/buttons

/add_button.gif" alt="Add from my address book" /></a>

– Specify the ID of your e-mail <textarea>– Specify the location of your hidden callback page

•Add a small callback page on your site<html><head><script type="text/javascript"

src="https://www.plaxo.com/ab_chooser/abc_comm.jsdyn">

</script></head><body></body></html>

•Full instructions and demo: http://www.plaxo.com/api

Page 17: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 17

What does Plaxo have to do?•Remember: Plaxo filled in a textarea on zazzle!

– Need to get around same-origin policy– Without server-side proxy (JS/HTML only)

• JSON-P won’t solve this problem– Widget popup is hosted by Plaxo and goes thru several steps– Zazzle doesn’t know when to request the contact data

•Solution: “The JavaScript Wormhole”– Add hidden callback page on zazzle that includes Plaxo script– Plaxo popup loads callback in an iframe when done– Script is dynamically generated, and includes selected data– IFrame is also on zazzle (and has the data), so it can tell

parent.opener to fill in the textfield

Page 18: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 18

zazzle.com/email_this plaxo.com/ab_chooser

plaxo.com/ab_chooser

Iframe: zazzle.com/cb.html Script: plaxo.com/ab_chooser/abc_comm.jsdyn

Page 19: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 19

Who’s using the Plaxo widget?

• See more at http://www.plaxo.com/api/gallery• Using the widget? Let us know!

Page 20: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 20

Generalizing the JavaScript Wormhole

• Site has a generic callback page to give you access– Site tells you the location of their callback page– Callback page loads your domain’s JavaScript

• JavaScript is dynamically generated to include your data

• Can pass script url with query args to callback page– /cb.html?http://foreign-site.com/json-api.js?name=val

– Access query string on cb page with location.search• Site can restrict callback page to trusted hosts

– Only load script if it’s on a trusted domain– Could further restrict to certain URL prefixes, etc.

Page 21: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 21

<html><head><title>Generalized JavaScript Wormhole</title><script type="text/javascript">var trustedDomains = [ "http://www.plaxo.com/api/", "http://www.google.com/"];

function isTrustedDomain(url) { for (var i = 0; i < trustedDomains.length; i++) if (url.indexOf(trustedDomains[i]) == 0) return true; return false;}

function doWormhole() { var url = location.search.substr(1); // chop off ? if (isTrustedDomain(url)) { var script = document.createElement('script'); script.type = "text/javascript"; script.src = url; document.getElementsByTagName("head")[0].appendChild(script); } else alert("ignoring untrusted url: " + url);}</script></head><body onload="doWormhole()"></body></html>

Page 22: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 22

Where do we go from here?

• Ajax is a “hack” on top of an old platform

• The platform can evolve

Page 23: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 23

Where do we go from here?

• Ajax is a “hack” on top of an old platform

• The platform is evolving

Page 24: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 24

Where do we go from here?

• Ajax is a “hack” on top of an old platform

• The platform is evolving

• What platform do we want to build?

Page 25: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 25

Should we open cross-domain XHR?

• After all, we can already include foreign JavaScript, image, and CSS files– So why not XML too? (“just another resource file”)

• HTML looks like XML (esp. XHTML)– Hard to make sure you really meant to serve that page

as XML data (cf. js / img / css)• Personal / private info more often in XML / HTML

– But increasingly a problem with JS too (JSON)• Cookies / creds sent with XHR request

– Can’t easily distinguish direct vs. XHR access

Page 26: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 26

Trust relationships between sites

• Random site accessing this file vs. trusted partner– Flash does this with crossdomain.xml– Web services do this with certs / IP whitelists– JavaScript wormhole does it (sort of)

• Should a trust relationship exist for mashups?– Want to minimize barriers to adoption / innovation– When sharing user info, should have prior agreement?– How formal / technical should this trust be?

Page 27: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 28

Proposals for better cross-site tools

• ContextAgnosticXmlHttpRequest (Chris Holland)– Alternative to normal XmlHttpRequest for cross-site– Don’t send/receive any cookie or HTTP auth info– Server must specify X-Allow-Foreign-Hosts in response

• JSONRequest (Douglas Crockford)– New browser object for cross-site JSON (like XHR)– Allows GET / POST / cancel of JSON request / response– No cookies / auth info sent or received– Requires special headers in request / response

Page 28: Plaxo OSCON 2006

Joseph Smarr - Cross-Site Ajax 29

In conclusion…

• Cross-site communication is tricky but important– Key enabling technology for building rich mashups

– Raises legitimate security issues that can’t be ignored

• Today: Use server-side proxy or JSON-P– Proxy introduces bottleneck, but provides full access

– JSON-P is more scalable, but limited to JSON APIs

– JavaScript Wormhole lets you touch foreign pages

• Keep the discussion of better tools / protocols going!– This problem is here to stay

– Browser developers are listening!