info343/lectures/jsonp-apis/index.shtml

<!--#include virtual="../s5/commontop.html" -->
      <title>Lecture 14: JSONP &amp; APIs — INFO 343 Autumn 2012</title>
   </head>

   <body>
      <div class="layout">
         <div id="controls"><!-- DO NOT EDIT --></div>
         <div id="currentSlide"><!-- DO NOT EDIT --></div>
         <div id="header"></div>
         <div id="footer">
            <h1>INFO 343 Lecture 14</h1>
            <h2>JSONP &amp; APIs</h2>
         </div>
      </div>

      <div class="presentation">
         <div class="slide">
            <h1>JSONP &amp; APIs</h1>
            <h3>Lecture 14</h3>
            <!-- <h4>Reading: 10.3–10.4</h4> -->

            <p class="license">
               © 2012 Morgan Doocy
            </p>

            <div class="w3c">
               <a href="http://validator.w3.org/check/referer"><img src="../s5/images/w3c-xhtml11.png" alt="Valid XHTML 1.1" /></a>
               <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="../s5/images/w3c-css.png" alt="Valid CSS!" /></a>
            </div>
         </div>
         
         
         
         <div class="slide">
            <h1>The Twitter Developers’ API</h1>
            
            <p class="description"><a href="https://dev.twitter.com/docs">https://dev.twitter.com/docs</a></p>
            
            <div style="float: right; width: 30%"><img src="developer.png"></div>
            
            <ul>
               <li>Developer tools for fetching &amp; embedding Twitter data
                  <ul>
                     <li>Specify search terms</li>
                     <li>Get tweets in JSON or XML</li>
                     <li>Embed tweets in your page</li>
                     <li>Get a user’s Twitter feed</li>
                     <li>etc.</li>
                  </ul>
               </li>
               <li>More detailed features require an <a href="https://dev.twitter.com/docs/auth/tokens-devtwittercom">authentication token</a></li>
               <li>Most web service data is accessed using the <a href="https://dev.twitter.com/docs/api/1.1">REST API</a></li>
               <li>We’ll use the <a href="https://dev.twitter.com/docs/api/1/get/search">older search API</a> because it doesn’t require authentication</li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>Problem: Loading data from another domain</h1>
            
<pre class="examplecode js">
$.get('http://<em>search.twitter.com</em>/search.json?q=beer', function(data) {
   <span class="comment">// never gonna happen :(</span>
   alert('Got data from Twitter!');
});
</pre>
            
            <ul>
               <li>Services like Google Maps, Twitter, etc. provide data in XML/JSON via web services</li>
               <li>We’d like to use that data in our JS application</li>
               <li>But browser blocks Ajax requests to other domains!
                  <ul>
                     <li>Called the <i>Same-Origin Policy</i></li>
                  </ul>
               </li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>Solution: <a href="http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/">JSONP</a></h1>
            <p class="description">A “cooperative cheat” to load data from another domain</p>
<pre class="syntaxtemplate js">
$.ajax('<var>url of web service on a different domain</var>', {
   <em>dataType: 'jsonp'</em>,
   success: <var>functionName</var>
});
</pre>
<p>This causes jQuery to dynamically inject this <code>script</code> tag:</p>
<pre class="syntaxtemplate html">
&lt;script src="<var>url of web service on a different domain</var><em>?callback=<var>functionName</var></em>"&gt;&lt;/script&gt;
</pre>
<p>If the web service supports the <code>callback</code> parameter, its output will be a JS call our <var>functionName</var> function, passing the data to it:</p>
<pre class="syntaxtemplate js">
<var>functionName</var>(<var>JS object data</var>);
</pre>
         </div>
         
         
         <div class="slide">
            <h1>Inspecting JSON results</h1>
            
            <div style="float: right; width: 60%"><img src="firebug-net-json.png" style="width: 100%" alt="Inspecting a JSONP result using Firebug's Net tab" /></div>
            
            <ul>
               <li>Use Firebug’s Net tab to inspect the JSONP request
                  <ul>
                     <li>(Won’t show up under Console since it isn’t a real Ajax request)</li>
                  </ul>
               </li>
               <li>Neatly formats the fields and values in the JSON response</li>
            </ul>
         </div>
         
         
         <div class="slide">
            <h1>Example: Loading tweets using JSONP</h1>
<div class="example">
<pre class="examplecode js">
$.ajax('<em>http://search.twitter.com/search.json</em>', {
   <em>data: { q: 'beer' },</em>
   <em>dataType: 'jsonp',</em>
   success: injectTweets
});

function injectTweets(<em>data</em>) {
   for (var i = 0; i &lt; data.results.length; i++) {
      var tweet = data.results[i]; <span class="comment">// the ith tweet in the results list</span>
      
      <span class="comment">// do something with this tweet</span>
   }
}
</pre>
</div>
            <ul>
               <li>Make request using <code>dataType: 'jsonp'</code> to get around the same-origin policy</li>
               <li>Inspect returned JSON data in Firebug’s Net tab (or paste into <a href="http://jsonlint.com/">JSONLint</a>) to see structure</li>
            </ul>
         </div>

         
         <div class="slide">
            <h1>Google Maps Developer API</h1>
            <p class="description"><a href="https://developers.google.com/maps/documentation/javascript/">https://developers.google.com/maps/documentation/javascript/</a></p>
            
            <style type="text/css">
               #map_canvas {
                  float: right;
                  width: 50%;
                  height: 13em;
                  background-color: fuchsia;
               }
            </style>
            <div id="map_canvas"></div>
            <script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=false"></script>
            <script type="text/javascript" charset="utf-8">
              var mapOptions = {
                center: new google.maps.LatLng(47.65484, -122.307973),
                zoom: 18,
                mapTypeId: google.maps.MapTypeId.HYBRID
              };
              var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
            </script>
            
            <ul>
               <li>Flexible, powerful mapping API with lots of features
                  <ul>
                     <li>Dynamically embed a map in your page</li>
                     <li>Specify zoom, center point, other options</li>
                     <li>Add markers, paths</li>
                     <li>Highlight areas, draw shapes</li>
                     <li>etc.</li>
                  </ul>
               </li>
               <li><strong style="font-style: italic">Should</strong> <a href="https://developers.google.com/maps/documentation/javascript/tutorial#api_key">obtain an API key</a>
                  <ul>
                     <li>(but it will let you use it a little without one)</li>
                  </ul>
               </li>
               <li><a href="https://developers.google.com/maps/documentation/javascript/tutorial">Basic tutorial</a>
                  <ul>
                     <li>More detailed tutorials: <a href="https://developers.google.com/maps/documentation/javascript/controls">Controls</a>, <a href="https://developers.google.com/maps/documentation/javascript/overlays">Overlays</a>, <a href="https://developers.google.com/maps/documentation/javascript/layers">Layers</a>, <a href="https://developers.google.com/maps/documentation/javascript/maptypes">Map Types</a></li>
                  </ul>
               </li>
               <li><a href="https://developers.google.com/maps/documentation/javascript/tutorial">Examples</a></li>
               <li><a href="https://developers.google.com/maps/documentation/javascript/reference">Full API documentation</a></li>
            </ul>
         </div>
         
         
         <div class="slide">
            <h1>Template: embedded Google map</h1>
<div class="example" style="font-size: 80%">
<pre class="examplecode html">
&lt;head&gt;
   ...
   <em>&lt;script src="//maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript" &gt;&lt;/script&gt;</em>
   &lt;style type="text/css"&gt;
      <span class="comment">/* must give the map container some dimensions for it to show up */</span>
      <em>#map_container { width: 50%; height: 10em; }</em>
   &lt;/style&gt;
   ...
&lt;/head&gt;
&lt;body&gt;
   <em>&lt;div id="map_container"&gt;&lt;/div&gt;</em>
</pre>
<pre class="examplecode js">
$(document).ready(function() {
   <em>initializeMap();</em>
});
function initializeMap() {
   <span class="comment">// an object that we'll use to specify options</span>
   <em>var mapOptions = {
      center: new google.maps.LatLng(-34.397, 150.644),
      zoom: 8,
      mapTypeId: google.maps.MapTypeId.ROADMAP
   };</em>
   <span class="comment">// the DOM object we're going to put the map into</span>
   var mapElement = document.getElementById("map_container");
   <span class="comment">// create the map inside mapElement with options specified by mapOptions</span>
   var map = <em>new google.maps.Map(mapElement, mapOptions);</em>
}
</pre>
</div>
         </div>
         
         
<!--#include virtual="../s5/commonbottom.html" -->