The jQuery Cross-Domain Ajax Guide « »

  • Tutorial
  • Ajax
Posted over 2 years ago


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 Wikipedia article.

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('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="/img/spacer.gif"> 

Flash Proxy

Cross-Domain requests with Flash must be specifically allowed by the domain you are about to query with a file called crossdomain.xml.

For example the search at Yahoo allows every domain while Twitters API only allows requests from their own master and sub domains.

<!DOCTYPE cross-domain-policy SYSTEM "www.adobe.com/xml/dtds/cross-domain-policy.dtd"> 
<cross-domain-policy> 
  <site-control permitted-cross-domain-policies="master-only" /> 
  <allow-access-from domain="*" /> 
</cross-domain-policy> 
<!-- ws02.ydn.ac4.yahoo.com compressed/chunked Mon Jan 25 14:58:30 PST 2010 --> 

<cross-domain-policy xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="www.adobe.com/xml/schemas/PolicyFile.xsd"> 
  <allow-access-from domain="twitter.com" /> 
    <allow-access-from domain="api.twitter.com" /> 
    <allow-access-from domain="search.twitter.com" /> 
    <allow-access-from domain="static.twitter.com" /> 
    <site-control permitted-cross-domain-policies="master-only"/> 
  <allow-http-request-headers-from domain="*.twitter.com" headers="*" secure="true"/> 
</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("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!

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.