Cross-Site Ajax Challenges and Techniques for Building Rich Web 2.0 Mashups Joseph Smarr Plaxo, Inc. [email_address]
The promise of mashups <ul><li>Create new experiences by combining  components from different authors </li></ul><ul><ul><l...
Talking between web components <ul><li>Normal situation : all on the same web site </li></ul><ul><ul><li>Communicate acros...
<ul><li>So, how do mashups communicate? </li></ul><ul><li>CAN  include image / JavaScript / CSS from Domain B   </li></ul>...
How do mashups communicate? <ul><li>Often, they don’t (Google maps 1.0) </li></ul><ul><ul><li>Single JavaScript    all pr...
Server-side proxy Web Page Domain A Server Domain A Server Domain B
How do mashups communicate? <ul><li>Often, they don’t (Google maps 1.0) </li></ul><ul><ul><li>Single JavaScript    all pr...
Flash proxy Web Page Domain A Server Domain B Flash crossdomain.xml
How do mashups communicate? <ul><li>JSON-P (Script injection + callback) </li></ul><ul><ul><li>Dynamically load JavaScript...
JSON-P Web Page Domain A Server Domain B <script> JSON + callback
Using JSON-P in OO web apps <ul><li>Problem : callback function has to be global </li></ul><ul><ul><li>Complex code mainta...
Dynamically binding a global callback <ul><li>var cbName = 'cb' + JSON.callbackCounter++; </li></ul><ul><li>var cbFunc = f...
Summary of cross-site techniques so far <ul><li>No cross-site communication </li></ul><ul><ul><li>Include partner’s JS fil...
What about updating another web page? <ul><li>Proxies / JSON-P let you access foreign data </li></ul><ul><ul><li>But still...
 
What does the partner site have to do? <ul><li>Add the  button to your page </li></ul><ul><ul><li><a onclick=&quot; showPl...
What does Plaxo have to do? <ul><li>Remember: Plaxo filled in a textarea on zazzle! </li></ul><ul><ul><li>Need to get arou...
zazzle.com/email_this plaxo.com/ab_chooser plaxo.com/ab_chooser Iframe: zazzle.com/cb.html    Script: plaxo.com/ab_choose...
Who’s using the Plaxo widget? <ul><li>See more at  http://www.plaxo.com/api/gallery </li></ul><ul><li>Using the widget? Le...
Generalizing the JavaScript Wormhole <ul><li>Site has a generic callback page to give you access </li></ul><ul><ul><li>Sit...
<ul><li><html><head><title>Generalized JavaScript Wormhole</title> </li></ul><ul><li><script type=&quot;text/javascript&qu...
Where do we go from here? <ul><li>Ajax is a “hack” on top of an old platform </li></ul><ul><li>The platform can evolve </l...
Where do we go from here? <ul><li>Ajax is a “hack” on top of an old platform </li></ul><ul><li>The platform is evolving </...
Where do we go from here? <ul><li>Ajax is a “hack” on top of an old platform </li></ul><ul><li>The platform is evolving </...
Should we open cross-domain XHR? <ul><li>After all, we can already include foreign JavaScript, image, and CSS files </li><...
Trust relationships between sites <ul><li>Random site accessing this file vs. trusted partner </li></ul><ul><ul><li>Flash ...
Restricting access to unauthorized info <ul><li>Restrict XHR to same “internet zone” </li></ul><ul><ul><li>So public site ...
Proposals for better cross-site tools  <ul><li>ContextAgnosticXmlHttpRequest  (Chris Holland) </li></ul><ul><ul><li>Altern...
In conclusion… <ul><li>Cross-site communication is tricky but important </li></ul><ul><ul><li>Key enabling technology for ...
For further reading… <ul><li>Cross-site limitations </li></ul><ul><ul><li>http://getahead.ltd.uk/ajax/cross-domain-xhr </l...
Upcoming SlideShare
Loading in...5
×

Joseph-Smarr-Plaxo-OSCON-2006

943

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
943
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
12
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Joseph-Smarr-Plaxo-OSCON-2006

  1. 1. Cross-Site Ajax Challenges and Techniques for Building Rich Web 2.0 Mashups Joseph Smarr Plaxo, Inc. [email_address]
  2. 2. The promise of mashups <ul><li>Create new experiences by combining components from different authors </li></ul><ul><ul><li>Each site focuses on what it does best </li></ul></ul><ul><ul><li>Can wire up components in a novel way </li></ul></ul><ul><ul><ul><li>Google maps + Craigslist = HousingMaps </li></ul></ul></ul><ul><li>Rich interaction often requires talking back and forth between components </li></ul><ul><ul><li>House’s address  lat / long  map it </li></ul></ul>
  3. 3. Talking between web components <ul><li>Normal situation : all on the same web site </li></ul><ul><ul><li>Communicate across frames / iframes / popups </li></ul></ul><ul><ul><li>Talk to server using AJAX (XMLHttpRequest) </li></ul></ul><ul><li>Problem : doesn’t work when components live at different domains (mashup situation) </li></ul><ul><ul><li>Same-origin policy </li></ul></ul><ul><ul><ul><li>Can include JavaScript / images from another domain </li></ul></ul></ul><ul><ul><ul><li>Can’t talk to frame / iframe popup or send an XHR </li></ul></ul></ul><ul><ul><ul><li>Prevents snooping on secret web pages (e.g. intranet) </li></ul></ul></ul>
  4. 4. <ul><li>So, how do mashups communicate? </li></ul><ul><li>CAN include image / JavaScript / CSS from Domain B </li></ul><ul><li>CAN send XMLHttpRequest to Domain A </li></ul><ul><li>CAN talk to other frames / iframes / popups on Domain A </li></ul><ul><li>CAN'T send XMLHttpRequest to Domain B </li></ul><ul><li>CAN'T talk to other frames / iframes / popups on Domain B </li></ul><ul><li>CAN talk to other pages on Domain A </li></ul><ul><li>CAN’T talk to any page on Domain A </li></ul>Domain B XML / Web Page XHR Image CSS JavaScript
  5. 5. How do mashups communicate? <ul><li>Often, they don’t (Google maps 1.0) </li></ul><ul><ul><li>Single JavaScript  all processing done locally </li></ul></ul><ul><ul><ul><li>Plotting lat/long or fetching image tiles is deterministic </li></ul></ul></ul><ul><ul><li>Can’t get any additional data (e.g. geo-coding) </li></ul></ul><ul><li>Server-side proxy (HousingMaps, Flickr) </li></ul><ul><ul><li>Talk to your server  it talks to the foreign site </li></ul></ul><ul><ul><li>Problem: bottleneck; barrier to mass deployment </li></ul></ul>
  6. 6. Server-side proxy Web Page Domain A Server Domain A Server Domain B
  7. 7. How do mashups communicate? <ul><li>Often, they don’t (Google maps 1.0) </li></ul><ul><ul><li>Single JavaScript  all processing done locally </li></ul></ul><ul><ul><ul><li>Plotting lat/long or fetching image tiles is deterministic </li></ul></ul></ul><ul><ul><li>Can’t get any additional data (e.g. geo-coding) </li></ul></ul><ul><li>Server-side proxy (HousingMaps, Flickr) </li></ul><ul><ul><li>Talk to your server  it talks to the foreign site </li></ul></ul><ul><ul><li>Problem: bottleneck; barrier to mass deployment </li></ul></ul><ul><li>Use flash for cross-domain communication </li></ul><ul><ul><li>Can use crossdomain.xml to allow foreign sites </li></ul></ul><ul><ul><li>Yahoo maps uses this to do geo-coding </li></ul></ul>
  8. 8. Flash proxy Web Page Domain A Server Domain B Flash crossdomain.xml
  9. 9. How do mashups communicate? <ul><li>JSON-P (Script injection + callback) </li></ul><ul><ul><li>Dynamically load JavaScript file with data </li></ul></ul><ul><ul><ul><li>Use DHTML to inject a <script> tag in the document </li></ul></ul></ul><ul><ul><ul><li>Data is returned in JSON (JavaScript data format) </li></ul></ul></ul><ul><ul><li>Clever trick: specify callback function on URL </li></ul></ul><ul><ul><ul><li>foreign-site.com/json-api.js? callback=myFunc </li></ul></ul></ul><ul><ul><ul><li>Loads myFunc ({ data: “hello” });  round-trip! </li></ul></ul></ul><ul><ul><li>Works well in practice, but some drawbacks </li></ul></ul><ul><ul><ul><li>Limited control vs. XHR (just loads or doesn’t) </li></ul></ul></ul><ul><ul><ul><li>API provider can return malicious code (e.g. steal cookies) </li></ul></ul></ul>
  10. 10. JSON-P Web Page Domain A Server Domain B <script> JSON + callback
  11. 11. Using JSON-P in OO web apps <ul><li>Problem : callback function has to be global </li></ul><ul><ul><li>Complex code maintains state / instances </li></ul></ul><ul><ul><li>Would like to handle callback with instance function on instantiated object </li></ul></ul><ul><li>Solution : bind the callback dynamically </li></ul><ul><ul><li>Create a globally-unique function name </li></ul></ul><ul><ul><ul><li>Usually global prefix + auto-incremented counter </li></ul></ul></ul><ul><ul><li>Use a closure to call your function in object-scope </li></ul></ul><ul><ul><li>Send the global function name as callback  it calls your scoped function </li></ul></ul>
  12. 12. Dynamically binding a global callback <ul><li>var cbName = 'cb' + JSON.callbackCounter++; </li></ul><ul><li>var cbFunc = function(jsonData) { </li></ul><ul><li>myFunc .call( myObj , jsonData); // call bound callback </li></ul><ul><li>}; </li></ul><ul><li>JSON.callbacks[cbName] = cbFunc; </li></ul><ul><li>var globalCallbackName = ‘JSON.callbacks.’ + cbName </li></ul><ul><li>// url: '/json-api.js?callback=' + globalCallbackName; </li></ul><ul><li>Used by dojo (ScriptSrcIO), Google Maps 2.5, Plaxo, etc. </li></ul>
  13. 13. Summary of cross-site techniques so far <ul><li>No cross-site communication </li></ul><ul><ul><li>Include partner’s JS file once (can’t talk again) </li></ul></ul><ul><li>Server-side proxy </li></ul><ul><ul><li>Talk on the backend (bottleneck, barrier to adoption) </li></ul></ul><ul><li>Flash proxy </li></ul><ul><ul><li>Talk through cross-domain flash (requires flash) </li></ul></ul><ul><li>JSON-P </li></ul><ul><ul><li>Talk through script-injection with callback (less control, partner could be malicious) </li></ul></ul>
  14. 14. What about updating another web page? <ul><li>Proxies / JSON-P let you access foreign data </li></ul><ul><ul><li>But still can’t touch a foreign frame/iframe/popup </li></ul></ul><ul><li>Many potential mashups would like to interact with existing web pages </li></ul><ul><ul><li>Auto-fill a form with your contact info </li></ul></ul><ul><ul><li>Highlight relevant search results / text snippets </li></ul></ul><ul><li>How can two sites that want to cooperate get around the same-origin policy? </li></ul>
  15. 16. What does the partner site have to do? <ul><li>Add the button to your page </li></ul><ul><ul><li><a onclick=&quot; showPlaxoABChooser('textarea', '/cb.html') ; return false&quot; href=&quot;#&quot;> </li></ul></ul><ul><ul><li><img src=&quot;http://www.plaxo.com/images/abc/buttons /add_button.gif&quot; alt=&quot;Add from my address book&quot; /></a> </li></ul></ul><ul><ul><li>Specify the ID of your e-mail <textarea> </li></ul></ul><ul><ul><li>Specify the location of your hidden callback page </li></ul></ul><ul><li>Add a small callback page on your site </li></ul><ul><ul><li><html><head><script type=&quot;text/javascript&quot; src=&quot;https://www.plaxo.com/ab_chooser/abc_comm.jsdyn&quot;> </script></head><body></body></html> </li></ul></ul><ul><li>Full instructions and demo: http:// www.plaxo.com/api </li></ul>
  16. 17. What does Plaxo have to do? <ul><li>Remember: Plaxo filled in a textarea on zazzle! </li></ul><ul><ul><li>Need to get around same-origin policy </li></ul></ul><ul><ul><li>Without server-side proxy (JS/HTML only) </li></ul></ul><ul><li>JSON-P won’t solve this problem </li></ul><ul><ul><li>Widget popup is hosted by Plaxo and goes thru several steps </li></ul></ul><ul><ul><li>Zazzle doesn’t know when to request the contact data </li></ul></ul><ul><li>Solution: “The JavaScript Wormhole” </li></ul><ul><ul><li>Add hidden callback page on zazzle that includes Plaxo script </li></ul></ul><ul><ul><li>Plaxo popup loads callback in an iframe when done </li></ul></ul><ul><ul><li>Script is dynamically generated, and includes selected data </li></ul></ul><ul><ul><li>IFrame is also on zazzle (and has the data), so it can tell parent.opener to fill in the textfield </li></ul></ul>
  17. 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
  18. 19. Who’s using the Plaxo widget? <ul><li>See more at http://www.plaxo.com/api/gallery </li></ul><ul><li>Using the widget? Let us know! </li></ul>
  19. 20. Generalizing the JavaScript Wormhole <ul><li>Site has a generic callback page to give you access </li></ul><ul><ul><li>Site tells you the location of their callback page </li></ul></ul><ul><ul><li>Callback page loads your domain’s JavaScript </li></ul></ul><ul><ul><ul><li>JavaScript is dynamically generated to include your data </li></ul></ul></ul><ul><li>Can pass script url with query args to callback page </li></ul><ul><ul><li>/cb.html? http://foreign-site.com/json-api.js?name=val </li></ul></ul><ul><ul><li>Access query string on cb page with location.search </li></ul></ul><ul><li>Site can restrict callback page to trusted hosts </li></ul><ul><ul><li>Only load script if it’s on a trusted domain </li></ul></ul><ul><ul><li>Could further restrict to certain URL prefixes, etc. </li></ul></ul>
  20. 21. <ul><li><html><head><title>Generalized JavaScript Wormhole</title> </li></ul><ul><li><script type=&quot;text/javascript&quot;> </li></ul><ul><li>var trustedDomains = [ </li></ul><ul><li>&quot;http://www.plaxo.com/api/&quot;, </li></ul><ul><li>&quot;http://www.google.com/&quot; </li></ul><ul><li>]; </li></ul><ul><li>function isTrustedDomain(url) { </li></ul><ul><li>for (var i = 0; i < trustedDomains.length; i++) </li></ul><ul><li>if (url.indexOf(trustedDomains[i]) == 0) </li></ul><ul><li>return true; </li></ul><ul><li>return false; </li></ul><ul><li>} </li></ul><ul><li>function doWormhole() { </li></ul><ul><li>var url = location.search.substr(1); // chop off ? </li></ul><ul><li>if (isTrustedDomain(url)) { </li></ul><ul><li>var script = document.createElement('script'); </li></ul><ul><li>script.type = &quot;text/javascript&quot;; </li></ul><ul><li>script.src = url; </li></ul><ul><li>document.getElementsByTagName(&quot;head&quot;)[0].appendChild(script); </li></ul><ul><li>} else alert(&quot;ignoring untrusted url: &quot; + url); </li></ul><ul><li>} </li></ul><ul><li></script></head><body onload=&quot;doWormhole()&quot;></body></html> </li></ul>
  21. 22. Where do we go from here? <ul><li>Ajax is a “hack” on top of an old platform </li></ul><ul><li>The platform can evolve </li></ul>
  22. 23. Where do we go from here? <ul><li>Ajax is a “hack” on top of an old platform </li></ul><ul><li>The platform is evolving </li></ul>
  23. 24. Where do we go from here? <ul><li>Ajax is a “hack” on top of an old platform </li></ul><ul><li>The platform is evolving </li></ul><ul><li>What platform do we want to build? </li></ul>
  24. 25. Should we open cross-domain XHR? <ul><li>After all, we can already include foreign JavaScript, image, and CSS files </li></ul><ul><ul><li>So why not XML too? (“just another resource file”) </li></ul></ul><ul><li>HTML looks like XML (esp. XHTML) </li></ul><ul><ul><li>Hard to make sure you really meant to serve that page as XML data (cf. js / img / css) </li></ul></ul><ul><li>Personal / private info more often in XML / HTML </li></ul><ul><ul><li>But increasingly a problem with JS too (JSON) </li></ul></ul><ul><li>Cookies / creds sent with XHR request </li></ul><ul><ul><li>Can’t easily distinguish direct vs. XHR access </li></ul></ul>
  25. 26. Trust relationships between sites <ul><li>Random site accessing this file vs. trusted partner </li></ul><ul><ul><li>Flash does this with crossdomain.xml </li></ul></ul><ul><ul><li>Web services do this with certs / IP whitelists </li></ul></ul><ul><ul><li>JavaScript wormhole does it (sort of) </li></ul></ul><ul><li>Should a trust relationship exist for mashups? </li></ul><ul><ul><li>Want to minimize barriers to adoption / innovation </li></ul></ul><ul><ul><li>When sharing user info, should have prior agreement? </li></ul></ul><ul><ul><li>How formal / technical should this trust be? </li></ul></ul>
  26. 27. Restricting access to unauthorized info <ul><li>Restrict XHR to same “internet zone” </li></ul><ul><ul><li>So public site can’t access intranet page </li></ul></ul><ul><li>Don’t send any cookies / credentials via XHR </li></ul><ul><ul><li>Practically restricts cross-site comm. to fully public info </li></ul></ul><ul><ul><li>Could still send auth info on URL </li></ul></ul><ul><ul><ul><li>But now other site has it </li></ul></ul></ul><ul><ul><ul><li>Give other site limited-access token? </li></ul></ul></ul><ul><li>White-list authorized sites with cross-domain file </li></ul><ul><li>Return special response headers for public pages </li></ul><ul><ul><li>Legacy problem for existing content </li></ul></ul>
  27. 28. Proposals for better cross-site tools <ul><li>ContextAgnosticXmlHttpRequest (Chris Holland) </li></ul><ul><ul><li>Alternative to normal XmlHttpRequest for cross-site </li></ul></ul><ul><ul><li>Don’t send/receive any cookie or HTTP auth info </li></ul></ul><ul><ul><li>Server must specify X-Allow-Foreign-Hosts in response </li></ul></ul><ul><li>JSONRequest (Douglas Crockford) </li></ul><ul><ul><li>New browser object for cross-site JSON (like XHR) </li></ul></ul><ul><ul><li>Allows GET / POST / cancel of JSON request / response </li></ul></ul><ul><ul><li>No cookies / auth info sent or received </li></ul></ul><ul><ul><li>Requires special headers in request / response </li></ul></ul>
  28. 29. In conclusion… <ul><li>Cross-site communication is tricky but important </li></ul><ul><ul><li>Key enabling technology for building rich mashups </li></ul></ul><ul><ul><li>Raises legitimate security issues that can’t be ignored </li></ul></ul><ul><li>Today: Use server-side proxy or JSON-P </li></ul><ul><ul><li>Proxy introduces bottleneck, but provides full access </li></ul></ul><ul><ul><li>JSON-P is more scalable, but limited to JSON APIs </li></ul></ul><ul><ul><li>JavaScript Wormhole lets you touch foreign pages </li></ul></ul><ul><li>Keep the discussion of better tools / protocols going! </li></ul><ul><ul><li>This problem is here to stay </li></ul></ul><ul><ul><li>Browser developers are listening! </li></ul></ul>
  29. 30. For further reading… <ul><li>Cross-site limitations </li></ul><ul><ul><li>http://getahead.ltd.uk/ajax/cross-domain-xhr </li></ul></ul><ul><ul><li>http:// msdn.microsoft.com/library/default.asp?url =/workshop/author/ om/xframe_scripting_security.asp </li></ul></ul><ul><li>FlashXMLHttpRequest </li></ul><ul><ul><li>http:// blog.monstuff.com/FlashXMLHttpRequest </li></ul></ul><ul><li>ContextAgnosticXMLHttpRequest </li></ul><ul><ul><li>http://chrisholland.blogspot.com/2005/03/contextagnosticxmlhttprequest-informal.html </li></ul></ul><ul><li>JSONRequest </li></ul><ul><ul><li>http:// json.org/JSONRequest.html </li></ul></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×