The jQuery Cross-Domain Ajax Guide

Saturday, August 7, 2010

JSONP

With "JSON with padding" you can request JSON formatted data from a 3rd party server. It makes usage of the script tag. Read more about it in the

This allows us to query any web API that returns JSON and allows a callback. In this quick example we query the Twitter API to find out the followers number of the @usejquery account.


$(document).ready(function() {
  $.getJSON('http://twitter.com/users/usejquery.json?callback=?', function(json) { //get information about the user usejquery from twitter api
    $('#twitter_followers').text(json.followers_count); //get the follower_count from the json object and put it in a span
  });
});

For further reading check out the article How to build a personal mashup page with jQuery .

'Screen Scraping' with some help of YQL

This technique is possible since Yahoo put out a service called Yahoo! Query Language . See the article An API for the Web: Learning YQL to learn more about YQL.

Basically we receive the HTML code of the requested website via YQL with a callback. Read more about it in the article Cross-Domain Requests with jQuery .

James Padolsey , author of the article linked above, also provides a Plugin called cross-domain-ajax which extends the Ajax abilities of jQuery with the YQL technique.

In this quick example we receive the HTML of the latest jQuery snippets on Snipplr and extract the titles and href's of the snippets. Traverse the received HTML like you would in your DOM!


<!-- include jQuery, cross-domain-ajax Plugin and our script -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.xdomainajax.js"></script>
<script type="text/javascript" src="js/main.js"></script>
$(document).ready(function() {
  $.get('http://snipplr.com/all/language/jquery', function(res) { //get the html source of this website
    $(res.responseText).find('.snippets li h3').each(function() { //loop though all h3 in the snippets list
      var anchor = $(this).children('a:last'); //get the actual link with the text inside
      jQuery('<li>', { //build a li element
        html: jQuery('<a>', { //with a A element inside it
          href: 'http://snipplr.com' + anchor.attr('href'), //set the href for the link
          text: anchor.text() //and the text
        })
     }).appendTo($('#jquery_snippets')); //append it to a list
   });
   $('#jquery_snippets li:first').remove(); //remove this first li ("Loading...") when done
});
});

</a></li>

  1. <cross-domain-policy>
  2. <site-control permitted-cross-domain-policies="master-only">
  3. <allow-access-from domain="*">
  4. </allow-access-from></site-control></cross-domain-policy>
  5. <!-- ws02.ydn.ac4.yahoo.com compressed/chunked Mon Jan 25 14:58:30 PST 2010 -->
  6. <cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nonamespaceschemalocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
  7. <allow-access-from domain="twitter.com">
  8. <allow-access-from domain="api.twitter.com">
  9. <allow-access-from domain="search.twitter.com">
  10. <allow-access-from domain="static.twitter.com">
  11. <site-control permitted-cross-domain-policies="master-only">
  12. <allow-http-request-headers-from domain="*.twitter.com" headers="*" secure="true">
  13. </allow-http-request-headers-from></site-control></allow-access-from></allow-access-from></allow-access-from></allow-access-from></cross-domain-policy>

That makes this technique only limited usable because mostly you want to request data from third party websites you are not in control of. If they forbid the request or don't have a crossdomain.xml file at all this technique is useless.

If you still want to check it out see flXHR (also has a jQuery adapter) and CrossXHR .

And what about some server-side help?!

You could also use a little server-side help like a PHP proxy. Read the article Loading external content with Ajax using jQuery and YQL by Christian Heilmann for more information on that topic (and of course even more on jQuery, Ajax and YQL).

Personally I think if you can control the server-side part of a project it is not reasonable to build a proxy. Remember: There are two (almost) exactly the same full requests. First the server-side part do a request and your client-side Ajax does the second request. Not DRY !

If you are in control of the server-side code I encourage you to format the data on the dedicated server , then and there. For example this website receives the Follower count from the Twitter API and only returns the number as text. Later on that number will be requested by Ajax.


class ThirdPartyStatsController < ApplicationController
  # ...
  def twitter
    response = Hash.from_xml open("http://twitter.com/users/show/usejquery.xml").read
    render :text => response["user"]["followers_count"]
  end
end

Conclusion

Cross-Domain requests via Ajax are possible but they should not be overdone. Weigh it for your own project and do smart coding!

If you are aware of any other client-side techniques please let us know in the comments!

 

Comments

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Target Image