I will be breaking down the post in to two sections.
First I will mention how to accomplish above mentioned task
using handlers and I will then go on and discuss the underlying concepts and
basic theories for the beginners in the next section.
How to get it
done!!!
What are the core parts we will need to perform a cross
domain request using JavaScript?
- A Mechanism to call the URL that sends data to the calling page.
- A padded JSON object (or a JSONP object)
- If the calling URL don’t support cross domain calls, functionality to wrap or pad the returned JSON object with a call back function.
- A method to handle the call back.
OK! Let’s take this one step at a time.
In this example I will be using JQuery AJAX facilities to
call the URL in the other domain.
jQuery.ajax
({
url:
"http://www.crosseddomain.com/testPage.html,
dataType:
"jsonp",
type:
"GET",
cache:
true,
jsonpCallback:
'handleResponse'
});
jsonpCallback option allows us to
specify the call back method which will handle the returned data upon the
response is received.
We specify cache as true to avoid the
random time stamp value JQuery appends on the request.
dataType is set to jsonp so
the call back function will be added to the request.
When the entire configuration is done correctly the page
will send a request like http://www.crosseddomain.com/testPage.html&callback=handleResponse
through the network.
Now all we have to do is write a function to handle the
returned value, the function name
should be the value we passed for the jsonpCallback option
function handleResponse(response) {
//your custom logic goes here
}
That will work only if the testPage.html wraps the response
with the call back. Or in other words if the requested page is responsible for
making the request cross domain compatible by converting the JSON object in to
a JSONP object by adding the call back function around it.
What shall we do when we are given a URL that does not
support cross domain script calls? How to make it JSONP compatible?
Normal JSON objects will not work across cross domains because
of the same origin policy, which
restricts browser side programming languages from accessing scripts in
another site or a domain. (I will talk about these theory parts in detail on
my next blog, so stay tuned).
So obviously it does not restrict server side programming
languages like C# from accessing URLs in separate domains.
Keeping that in mind, we can send the request for the URL
from server side, after receiving the normal response we can wrap it with the
call back function and we can send it to the page where the call originated from.
To get this done we will use a generic web handler or an
ashx file.
For demonstration purposes, the handler will be expecting
some string data from the requesting page and it will send a dummy JSON object
that contains user inputted data with some custom data from the server side. (To
make things simple I will not add the code to do an actual web request, rather
I will just hard code the JSON string).
I will add a text box to the page and will get the user input
in each key press. After a response is received the call back function will
display retrieved data in a label.
The HTML markup will be
<div>
Enter your text : <input type="text" id="suggest"
name="Suggestion"
/>
div>
<label id="results">
label>
And the JQuery request will look something like this.
$(document).ready(function () {
$("#suggest").keyup(function () {
var
data = $("#suggest").val();
jQuery.ajax({
url: "http://localhost:18395/RequestHandler.ashx?data="
+ data,
dataType: "jsonp",
type: "GET",
cache: true,
jsonpCallback: 'handleResponse'
});
});
});
The RequestHandler.ashx file code is mentioned below.
public class
RequestHandler : IHttpHandler
{
public void ProcessRequest(HttpContext
context)
{
var
data = context.Request.QueryString["data"];
var
callback = context.Request.QueryString["callback"];
var
response = context.Response;
response.Clear();
response.ContentType = "application/json";
var
sampleJson = "{\"firstName\":\"Dhanushka\",\"lastName\":\"Athukorala\",\"dataReceived\":\""
+ data + "\"}";
var
paddedResponse = string.Format("{0}({1})", callback, sampleJson);
response.Write(paddedResponse);
response.Flush();
}
public bool IsReusable
{
get
{
return
false;
}
}
}
So let’s see what’s happening in the code behind file.
- We retrieve data passed from the user from the query string (data variable)
- Call back function name is also retrieved from the query string (callback variable)
- A JSON object is created (this is the line where you have to call a URL and get data, you can use the functionalities implemented in HttpWebRequest, HttpWebResponse to accomplish this)
- We wrap the final JSON object with the call back function so it will be in the format callback(JSON) making it a JSONP object (paddedResponse variable)
- The JSONP object is written to the response making it available for the calling page.
Now when the response is flushed it will return back to the
calling page. Here the script tag of that page will execute received data or
the JSONP object, or in other words it will call the call back method with a
JSON object.
The code for our call back method is mentioned below.
function handleResponse(response) {
var
data = eval(response);
var
firstName = data.firstName;
var
lastName = data.lastName;
var
sentData = data.dataReceived;
$("#results").html("First Name : " + firstName + "
Last Name : " + lastName + "
Sent Data : " + sentData);
Last Name : " + lastName + "
Sent Data : " + sentData);
}
This call back method will process the returned JSON string
and will print the containing information in the results label
So in a nut shell the codes we need are
Script tag and the HTML
Handler code
And the out put will be
Hope it helps.
I will explain the underlying principals of cross domain communication with scripts in the second part of this blog.
Cheers!!