Home / AJAX

HOW TO Use JSONP to Request Data from Remote Websites

RSS
Modified on 2009/12/04 18:02 by Stephen Walther Categorized as Uncategorized
Many popular websites such as Flickr, Bing and Delicious provide REST-based APIs that allow clients to retrieve data in different formats. Some services return SOAP (Simple Object Access Protocol) or POX (Plain Old XML) messages while others support JSON (JavaScript Object Notation) or JSONP (JSON with padding). The ASP.NET Ajax Library provides support for working with different types of data formats such as JSONP and can be used in harmony with other script libraries to send requests to REST services and process data that's returned. This tutorial will demonstrate how to use jQuery together with the ASP.NET Ajax Library's DataView object to retrieve data from the Bing search API and bind it to a template. Topics covered include:

  1. Loading Required Scripts
  2. Calling the Bing Search Service
  3. Binding Data To a Template

Step 1: Loading Required Scripts

The ASP.NET Ajax Library's Script Loader can be used to load the scripts that are needed to call the Bing search service. The following code loads the scripts required by the library's DataView component as well as the jQuery library.

<script src="http://ajax.microsoft.com/ajax/beta/0911/Start.js" type="text/javascript"></script>
<script type="text/javascript">

var appId = "BC013DE2CFB14E0C34BDAFDB1F2020FDA3965134"; var count = 5;

Sys.require([Sys.components.dataView, Sys.scripts.WebServices, Sys.scripts.jQuery], function() { // Add button handler $("#btnQuery").click( performQuery );

// Create a DataView $("#resultsView").dataView(); }); </script>


In this example the Script Loader retrieves the Start.js script from the Microsoft Ajax Content Delivery Network (CDN) which causes all of the other required scripts to be loaded from the CDN by default providing speed and caching efficiencies. Once the scripts are loaded jQuery features are used to attach a click event handler to a function named performQuery and to create a new DataView component. Note that the location where scripts are loaded can be overidden in cases where a specific script such as jQuery needs to be loaded locally. For example, jQuery can be loaded locally by adding the following code above the call to Sys.require:

Sys.scripts.jQuery.releaseUrl = "../Scripts/jquery-1.3.2.min.js";

Step 2: Calling the Bing Search Service

When the performQuery function is called a jsonRequest variable is created that builds up the URI needed to call the Bing service. jQuery's getJSON function is then called to initiate the request and a callback function is passed into it named queryComplete:

function performQuery() {
    var queryText = $("#query").val();

// Format the JSON request var jsonRequest = "http://api.search.live.net/json.aspx?" + "sources=web" + "&JsonType=callback" + "&Appid=" + appId + "&query=" + encodeURI(queryText) + "&web.count=" + count + "&JSONCallback=?"

// Make the JSON request $.getJSON(jsonRequest, queryComplete); }

Step 3: Binding Data to a Template

When the Bing service call returns data the queryComplete function is called and the data is then bound to a template using the DataView object created earlier. The queryComplete function locates the DataView attached to the template using Sys.get("$resultsView") and calls its set_data function:

function queryComplete(results) {
    Sys.get("$resultsView").set_data(results.SearchResponse.Web.Results);
}

The template that the DataView component is bound to is shown next. The template uses the PropertyName one-time binding syntax to bind the URL, Title and Description properties.

<body>

<input id="query" /> <button id="btnQuery">Submit</button>

<ul id="resultsView" class="sys-template"> <li> <a sys:href="{{Url}}">{{Title}}</a> <p sys:if="$dataItem.Description"> {{Description}} </p> </li> </ul>

</body>


The complete code for the page that calls the Bing service follows:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Show Bing Search</title>

<style type="text/css"> .sys-template { display: none; } #resultsView { font: 11px Arial; width:250px; } #resultsView p { margin-top:0px; margin-bottom:10px; }

</style>

<script src="http://ajax.microsoft.com/ajax/beta/0911/start.debug.js" type="text/javascript"></script> <script type="text/javascript">

var appId = "BC013DE2CFB14E0C34BDAFDB1F2020FDA3965134"; var count = 5;

Sys.require([Sys.components.dataView, Sys.scripts.WebServices, Sys.scripts.jQuery], function() { // Add button handler $("#btnQuery").click( performQuery );

// Create a DataView $("#resultsView").dataView(); }); function performQuery() { var queryText = $("#query").val();

// Format the JSON request var jsonRequest = "http://api.search.live.net/json.aspx?" + "sources=web" + "&JsonType=callback" + "&Appid=" + appId + "&query=" + encodeURI(queryText) + "&web.count=" + count + "&JSONCallback=?"

// Make the JSON request $.getJSON(jsonRequest, queryComplete); }

// When the JSON request completes, show the news function queryComplete(results) { Sys.get("$resultsView").set_data(results.SearchResponse.Web.Results); }

// If there is an error, show it function queryFail(err) { alert(err.get_message()); } </script>

</head> <body>

<input id="query" /> <button id="btnQuery">Submit</button>

<ul id="resultsView" class="sys-template"> <li> <a sys:href="{{Url}}">{{Title}}</a> <p sys:if="$dataItem.Description"> {{Description}} </p> </li> </ul>

</body> </html>