So I have
a fun a little project where I was playing around with the
Yahoo Local Search API. I really like Yahoo's local search. I think it is much better than Google's, though in all fairness that opinion was formed 18+ months ago. They have a great open API. Of course they place a limitation on how much you can use. What's interesting is that usage is tied to IP address. The limit is 5000 queries per day per IP address.
This of course begs for Cross Site Scripting(XSS.) If the call to their API to happen from a user's browser, then it counts against that individual user's 5000 query limit. One obvious way to accomplish is this is with Flex. That's because the Yahoo API server farm has
an open policy for Flash.
Another way is via JavaScript. Of course I can't make an XMLHttpRequest directly from a user's browser to Yahoo because of browser security. Luckily Yahoo encourages Cross Site Script. You can make a request to their local search API with response output set to JSON and with a callback method. From there you just need some sneaky JavaScript:
function search(lat,lng,cat){
var reqUrl = "http://local.yahooapis.com/LocalSearchService"+
"/V2/localSearch?appid=YahooDemo&"+
"output=json&callback=showResults";
var req = reqUrl + "&query="+cat+"&latitude="
+lat+"&longitude="+lng;
var rdiv = document.getElementById("resultlist");
var jsonp = document.createElement("script");
jsonp.setAttribute("type","text/javascript");
jsonp.setAttribute("src",req);
rdiv.appendChild(jsonp);
}
The sneaky part here is creating a "script" DOM element, setting its src attribute to the dynamic URL, and then dropping it into the main page DOM. It gets evaluated immediately. The URL response looks like:
showResults({"ResultSet":{"totalResultsAvailable":3423,"totalResultsReturned":10,"firstResultPosition"
:1,"ResultSetMapUrl":"http:\/\/local.yahoo.com\/mapview?stx=coffee&radius=50&ed=sh5iF6131DyGMtZvcmi9jNSxMpMwUjolfcSc44DLrkDbXpY-"
,"Result":[{"Title":"City Espresso Gourmet Coffee","Address":"630 Blossom Hill Rd","City":"San Jose"
,"State":"CA","Phone":"(408) 972-4500","Latitude":"37.250463","Longitude":"-121.8436","Rating":{"AverageRating"
:"","TotalRatings":"0","TotalReviews":"0"},"Distance":"1.18","Url":"http:\/\/local.yahoo.com\/details
?id=21609154&stx=coffee&csz=San+Jose+CA&ed=WbZ4Ba160SzTaXFlbDSmVAyxneC9N59mhMtS3xZb6kL86aeI4P1iTZT5BJOOXR5qK9HSoV5KX0wL"
,"ClickUrl":"http:\/\/local.yahoo.com\/details?id=21609154&stx=coffee&csz=San+Jose+CA&ed=WbZ4Ba160SzTaXFlbDSmVAyxneC9N59mhMtS3xZb6kL86aeI4P1iTZT5BJOOXR5qK9HSoV5KX0wL"
,"MapUrl":"http:\/\/maps.yahoo.com\/maps_result?name=City+Espresso+Gourmet+Coffee&desc=4089724500&csz
=San+Jose+CA&qty=9&cs=9&ed=WbZ4Ba160SzTaXFlbDSmVAyxneC9N59mhMtS3xZb6kL86aeI4P1iTZT5BJOOXR5qK9HSoV5KX0wL
&gid1=21609154","BusinessUrl":"","BusinessClickUrl":""}]}});
The function showResults gets evaluated with the results from Yahoo. How nice of Yahoo to support
JSONP. The
eBay APIs also have great support for this technique.