2006-12-18
Cross Domain JSON with fjsc
I've added support to fjsc for cross domain AJAX calls to web services that use the JSON format.
Usually Ajax requests from a web page are limited to requesting resources on the server that the web page originated from. A way to work around this is to load cross domain Javascript by creating an HTML SCRIPT tag dynamically, setting the 'src' attribute to the resource required, and inserting it into the HEAD of the document. This results in the script being executed. Here is some jQuery code that demonstrates this:
$("head/script#jsonrequest").remove();
var script = document.createElement("script");
script.id = "jsonrequest";
script.type = "text/javascript";
script.src = "http://someotherdomain.com/test.js";
$("head").append(script);
A problem with this approach is that if the src URL points to JSON data then it gets evaluated but you can't do anything with it since JSON is data, not code.
Bob Ippolito described the idea of JSONP. This is a JSON file served by a remote server that allows the resulting JSON to be wrapped in a function call named by a parameter passed to the URL of the service. This means the data is now executed by a function chosen by the web page author and can process the data. Something like this would be how you could use such a service:
function handler(data) { alert(data); }
$("head/script#jsonrequest").remove();
var script = document.createElement("script");
script.id = "jsonrequest";
script.type = "text/javascript";
script.src = "http://someotherdomain.com/myapi?callback=handler";
$("head").append(script);
This is what I've added to fjsc. Two new words:
- load-script ( url -- )
- Dynamically add a script tag to the page that loads and evaluates the given URL
- json-request ( url -- data )
- Calls load-request to load and evaluate the given URL. The URL should be to a JSON service with a query parameter that allows a callback function name to be inserted into the JSON result. Use `handle_json` as the callback name. This will result in the data from the service being left on the stack.
An example using Yahoo's image search:
"http://api.search.yahoo.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=factor+language&output=json&callback=handle_json"
json-request
"ResultSet" swap alien-property
"totalResultsAvailable" swap alien-property alert
This makes the call to the service using the Cross Domain JSON functionality. It takes the 'ResultSet' member from the returned Javascript object, and the 'totalResultsAvailable' member from that to display in an alert box.
There are some security considerations to keep in mind when doing cross domain calls this way. The server receiving the request can inject any javascript into the result. What they can do is limited due to the Javascript sandbox but a carefully crafted injection could do bad things. They receiving server also has access to all the cookies and resources that the originating web page has. See here for some questions and answers on this approach.