English | Site Directory

Google AJAX Feed API

Developer's Guide

With the AJAX Feed API, you can download any public Atom or RSS feed using only JavaScript, so you can easily mash up feeds with your content and other APIs like the Google Maps API. To use the API, you need to sign up for an API key, and then follow the instructions below.

The API is new, so there may be bugs and slightly less than perfect documentation. Bear with us as we fill in the holes, and join the AJAX APIs developer forum to give feedback and discuss the API.

Table of Contents

Audience

This documentation is designed for people familiar with JavaScript programming and object-oriented programming concepts. There are many JavaScript tutorials available on the Web.

Introduction

With the AJAX Feed API, you can download any public Atom or RSS feed using only JavaScript, so you can easily mash up feeds with your content and other APIs like the Google Maps API. See the program below for a simple example.

JavaScript and XMLHttpRequest use the Same-Origin Policy (SOP). With this policy, scripts can access data from the same host from which the containing page of HTML was served, but not other hosts. This protects users from certain classes of scripting attacks, but prevents many developers from writing AJAX-based mashups. The Google AJAX Feed API offers a simple workaround to these restrictions for a specific type of content available on the web: syndication feeds. See the security notes below for more details about how the AJAX Feed API preserves user security.

The "Hello, World" of the Google AJAX Feed API

The easiest way to start learning about this API is to see a simple example. The following example downloads the Digg RSS feed and displays the feed entry titles to the user:

<html>
  <head>
    <script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_KEY_HERE"></script>
    <script type="text/javascript">

    google.load("feeds", "1");

    function initialize() {
      var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
      feed.load(function(result) {
        if (!result.error) {
          var container = document.getElementById("feed");
          for (var i = 0; i < result.feed.entries.length; i++) {
            var entry = result.feed.entries[i];
            var div = document.createElement("div");
            div.appendChild(document.createTextNode(entry.title));
            container.appendChild(div);
          }
        }
      });
    }
    google.setOnLoadCallback(initialize);

    </script>
  </head>
  <body>
    <div id="feed"></div>
  </body>
</html>

You can download this example to edit and play around with it, but you'll have to replace the key in that file with your own Google API key.

Including the AJAX Feed API on Your Page

To include the AJAX Feed API in your page, you need to both include the Google AJAX APIs script tag and call google.load("feeds", "1"):

<script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_KEY_HERE"></script>
<script type="text/javascript">
  google.load("feeds", "1");
</script>

The first script tag loads the google.load function, which lets you load individual Google APIs. google.load("feeds", "1") loads Version 1 of the feeds API. Currently the AJAX Feed API is in Version 1, but new versions may be available in the future. See the versioning discussion below for more information.

Loading the API requires two steps because Google is moving to a new model of loading AJAX APIs to make it easier to include multiple Google APIs on your pages. Subscribe to the Google AJAX APIs Blog for announcements as we start rolling out this new AJAX API loading mechanism.

JSON and XML Result Formats

The AJAX Feed API can return feeds in two formats: JSON and XML. By default, the API returns the feed in the JSON format.

The AJAX Feed API JSON format is an abbreviated, canonicalized version of the original feed. It maps Atom and RSS attributes like title, description, and summary to a set of common JSON properties so that you can access Atom and RSS feeds uniformly. For example, the JSON result format returns RSS attribute description as the JSON property content, just like Atom. Likewise, the RSS element pubDate is returned as the JSON property publishedDate to make the results uniform with Atom feeds. The JSON result format is useful if you only want to access standard RSS and Atom elements, and you don't want to worry about the differences between feed formats. See the JSON example below or JSON result format specification for information.

If you specify the XML result format with setResultFormat, the AJAX Feed API will return the complete feed XML instead of JSON results. You can access the XML document with the standard XML DOM functions built into the browser. The XML result format is useful if you prefer using DOM functions to JSON or you need to access extension elements in the feed, like digg:diggCount. See the XML example below or XML result format specification for information.

You can also use both the JSON properties and the XML document to get the benefits of canonicalized attributes and access to XML extension elements. See the combined XML/JSON example below that uses the JSON attributes to access all of the entries in the feed, but uses the XML DOM to get the custom Digg digg:diggVotes element in the feed.

API Updates

The second argument to google.load is the version of the AJAX Feed API you are using. Currently the AJAX Feed API is in version 1, but new versions may be available in the future.

If we do a significant update to the API in the future, we will change the version number and post a notice on Google Code and the AJAX APIs discussion group. When that happens, we expect to support both versions for at least a month in order to allow you to migrate your code.

The AJAX Feed API team periodically updates the API with the most recent bug fixes and performance enhancements. These bug fixes should only improve performance and fix bugs, but we may inadvertently break some API clients. Please use the AJAX APIs discussion group to report such issues.

Examples

The Basics

This example downloads a single feed and displays the title of each entry to the user.

var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.load(function(result) {
  if (!result.error) {
    var container = document.getElementById("feed");
    for (var i = 0; i < result.feed.entries.length; i++) {
      var entry = result.feed.entries[i];
      var div = document.createElement("div");
      div.appendChild(document.createTextNode(entry.title));
      container.appendChild(div);
    }
  }
});

View example (helloworld.html)

JSON Result Format

This example is similar to the simple example above, but it displays most of the canonical JSON properties exposed by the AJAX Feed API. See the JSON result format specification for information.

var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.load(function(result) {
  if (!result.error) {
    var container = document.getElementById("feed");
    for (var i = 0; i < result.feed.entries.length; i++) {
      var entry = result.feed.entries[i];
      var attributes = ["title", "link", "publishedDate", "contentSnippet"];
      for (var j = 0; j < attributes.length; j++) {
        var div = document.createElement("div");
        div.appendChild(document.createTextNode(entry[attributes[j]]));
        container.appendChild(div);
      }
    }
  }
});

View example (json.html)

XML Result Format

The following examples show how to access an RSS and Atom feed through the XML DOM rather than using the JSON results returned by the AJAX Feed API. The difference between accessing the two feeds is that the RSS example uses the RSS elements such as item and the Atom example uses Atom elements such as entry.

The first example directly accesses an RSS feed through the XML DOM. In the example, we take advantage of the getElementsByTagNameNS included in the AJAX Feed API to access the diggCount extension element in the Digg feed, which lets us display the number of votes next to the title in the output.

var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.setResultFormat(google.feeds.Feed.XML_FORMAT);
feed.load(function(result) {
  var container = document.getElementById("feed");
  if (!result.error) {
    var items = result.xmlDocument.getElementsByTagName("item");
    for (var i = 0; i < items.length; i++) {
      var titleElement = items[i].getElementsByTagName("title")[0];
      var title = titleElement.firstChild.nodeValue;

      var votesElement = google.feeds.getElementsByTagNameNS(items[i], "http://digg.com/docs/diggrss/", "diggCount")[0];
      var votes = votesElement.firstChild.nodeValue;

      var div = document.createElement("div");
      div.appendChild(document.createTextNode(title + " (" + votes + " votes)"));
      container.appendChild(div);
    }
  }
});

View example (xml.html)

The second example directly accesses an Atom feed through the XML DOM. In this example, we again take advantage of the getElementsByTagNameNS included in the AJAX Feed API to access the elements in the Google Base feed.

var feed = new google.feeds.Feed("http://www.google.com/base/feeds/snippets");
feed.setResultFormat(google.feeds.Feed.XML_FORMAT);
feed.load(function(result) {
  var container = document.getElementById("feed");
  if (!result.error) {
    var entries = google.feeds.getElementsByTagNameNS(result.xmlDocument, "http://www.w3.org/2005/Atom", "entry");
    for (var i = 0; i < entries.length; i++) {
      var titleElement = google.feeds.getElementsByTagNameNS(entries[i], "http://www.w3.org/2005/Atom", "title")[0];
      var title = titleElement.firstChild.nodeValue;

      var priceElement = google.feeds.getElementsByTagNameNS(entries[i], "http://base.google.com/ns/1.0", "price")[0];
      var price = priceElement.firstChild.nodeValue;

      var div = document.createElement("div");
      div.appendChild(document.createTextNode(title + " (" + price + ")"));
      container.appendChild(div);
    }
  }
});

View example (atomxml.html)

Combined JSON/XML Result Format

This example reproduces the output of the XML example above, but combines usage of the JSON result format and access to the XML DOM. We iterate over all of the elements in the feed using the JSON data structure returned by the AJAX Feed API, and we use the special xmlNode pointer in each JSON result to access the element in the XML DOM corresponding to that entry. We use that XML element and getElementsByTagNameNS to access the diggCount extension element, which gives us access to the number of votes for that Digg story.

var feed = new google.feeds.Feed("http://www.digg.com/rss/index.xml");
feed.setResultFormat(google.feeds.Feed.MIXED_FORMAT);
feed.load(function(result) {
  if (!result.error) {
    var container = document.getElementById("feed");
    for (var i = 0; i < result.feed.entries.length; i++) {
      var entry = result.feed.entries[i];
      var votesElement = google.feeds.getElementsByTagNameNS(entry.xmlNode, "http://digg.com/docs/diggrss/", "diggCount")[0];
      var votes = votesElement.firstChild.nodeValue;

      var div = document.createElement("div");
      div.appendChild(document.createTextNode(entry.title + " (" + votes + "votes)"));
      container.appendChild(div);
    }
  }
});

View example (jsonxml.html)

The FeedControlNew!

This example uses the higher level google.feeds.FeedControl class to display a collection of feeds. This class is similar to the AJAX Search API's Search Control layer GSearchControl. This example creates a FeedControl class, adds two feeds into the class, and then tells the feed control to draw.

<html>
  <head>
    <script  type="text/javascript" src="http://www.google.com/jsapi?key="YOUR-KEY"></script>
    <script type="text/javascript">
      
      google.load("feeds", "1");

      function initialize() {
        var feedControl = new google.feeds.FeedControl();
        feedControl.addFeed("http://www.digg.com/rss/index.xml", "Digg");
        feedControl.addFeed("http://feeds.feedburner.com/Techcrunch", "TechCrunch");
        feedControl.draw(document.getElementById("feedControl"));
      }
      google.setOnLoadCallback(initialize);

    </script>
  </head>

  <body>
    <div id="feedControl">Loading</div>
  </body>
</html>

View example (feedcontrol.html)

Discovering FeedsNew!

These two examples use the global methods, google.feeds.findFeeds and google.feeds.lookupFeed, to discover feeds based on search terms and to lookup feeds associated with standard web pages.

The first sample uses the google.feeds.findFeeds to dynamically populate a FeedControl based on search terms.

<html>
  <head>
    <script  type="text/javascript" src="http://www.google.com/jsapi?key="YOUR-KEY"></script>
    <script type="text/javascript">
      
      google.load("feeds", "1");

      var defaultQuery = 'Official Google Blogs';

      function findFeeds(query) {
        google.feeds.findFeeds(query, feedSearchDone);
      }

      function feedSearchDone(result) {
        var el = document.getElementById('feedControl');

        if (result.error || result.entries.length <= 0) {
          el.innerHTML = 'No Results Found';
          return;
        }

        // Create a feed control
        var feedControl = new google.feeds.FeedControl();

        // Grab top 4..
        for (var i = 0; i < 4; i++) {
          feedControl.addFeed(result.entries[i].url, result.entries[i].title);
        }

        feedControl.setLinkTarget(google.feeds.LINK_TARGET_BLANK);
        feedControl.setNumEntries(2);
        feedControl.draw(el);
      }

      google.setOnLoadCallback(function() {findFeeds(defaultQuery)});

    </script>
  </head>

  <body>
    <div id="feedControl">Loading</div>
  </body>
</html>

View example (findfeeds.html)

The second sample uses the google.feeds.lookupFeed to get the feed associated with a public Flickr web page for a given user and then dynamically populate a slideshow.

<html>
  <head>
    <script  type="text/javascript" src="http://www.google.com/jsapi?key="YOUR-KEY"></script>
    <script type="text/javascript">
      
      google.load("feeds", "1");

      var defaultUser = 'dlc0421';

      function newSlideShow(user) {
        showStatus('Resolving feed for ' + user);
        var url = 'http://www.flickr.com/photos/' + user;
        google.feeds.lookupFeed(url, lookupDone);
      }

      function lookupDone(result) {
        if (result.error || result.url == null) {
        showStatus('Could not locate feed for user');
	return;
        }

        showStatus('Found Photo Feed');
        // We need to switch over from Atom to RSS to get Yahoo Media for slideshow..
        var url = result.url.replace('format=atom', 'format=rss_200');
        showSlideShow(url);
      }

      function showSlideShow(url) {
        var options = {
          displayTime: 2500,
          transistionTime: 800,
          scaleImages: true,
          thumbnailTag: 'content',
          linkTarget : google.feeds.LINK_TARGET_BLANK
        };
        new GFslideShow(url, "slideshow", options);
      }

      google.setOnLoadCallback(function() {newSlideShow(defaultUser)});

    </script>
  </head>

  <body>
    <div id="feedControl">Loading</div>
  </body>
</html>

View example (lookup.html)

API Details

Supported Feed Formats

The Google AJAX Feed API supports the following feed formats:

Discovering Feeds

The Google AJAX Feed API now supports additional global methods, google.feeds.findFeeds and google.feeds.lookupFeed which can be used to search for relevant feeds and lookup the associated feed for an HTML based URL.

How Feeds are Crawled

The Google AJAX Feed API crawls feeds with Feedfetcher, which is also used for Google Reader and the Google personalized homepage. See the Google Webmaster Help Center for details on Feedfetcher.

Feed Crawl Frequency

As the Google AJAX Feed API uses Feedfetcher, feed data from the AJAX Feed API may not always be up to date. The Google feed crawler ("Feedfetcher") retrieves feeds from most sites less than once every hour. Some frequently updated sites may be refreshed more often.

Cross-Browser XML Access

Microsoft Internet Explorer does not support DOM Level 2, which means that it does not support namespace-aware DOM functions like getElementsByTagNameNS. The Google AJAX Feed API includes a cross-browser implementation of getElementsByTagNameNS since it is a common requirement for sites consuming feeds. The API does not include implementations of any other DOM Level 2 methods at this time.

Security Notes

JavaScript uses the Same-Origin Policy (SOP) to prevent malicious scripts from accessing private user data. See the Security for GWT Applications article for an in-depth discussion on the implications of this policy and other JavaScript security issues.

The AJAX Feed API does not send any private information to the host of the requested feeds (e.g., digg.com). Google's crawler Feedfetcher downloads the feeds anonymously, and Google's servers act as a cache for that feed for all requests made with the AJAX Feed API. The AJAX Feed API only provides access to publicly accessible feeds.

Troubleshooting

If you encounter problems with your code:

  • Make sure your API key is valid.
  • Look for typos. Remember that JavaScript is a case-sensitive language.
  • Use a JavaScript debugger. In Firefox, you can use the JavaScript console or the FireBug extension. In IE, you can use the Microsoft Script Debugger.
  • Search the AJAX APIs discussion group. If you can't find a post that answers your question, post your question to the group along with a link to a web page that demonstrates the problem.