Jul

29

Ajax and and HTTP Request, JSONP with the script element Prt.8

JSONP with the script element

As you can remember in earlier posts I mention that a <script> element can be used as an Ajax

transport mechanism: simply set the src attribute of the <script > elemment an the brwser will generate the an HTTP request to download the URL you have specified. <script > elements are useful Ajax transports for one primary reason : They are not subject to the same-origin policy, so you can use them to request dat from servers with different origns. A second reason is that the <script > element automaticall decode and execute the response bodies that contain JSON-encoded data.

The technique of using a <script> elements as an Ajax transport has come to be known JSONP : It works when response body of the HTTP request is JSON-encoded. The “P” stands for “padding” or “prefix”

Supposed you’ev written a service a service that handles GET request and returned
JSON-encoded data. Same-origin documents can use it with XMLHttpRequest and JSON.parse().
If you enable CORS on your server, Cross-origin document in new browsers can also
use your service with XMLHttpRequest. Cross-origin document in older browser that do not
support CORS can only access your service using <script> elements however.
Your JSON response body is valid javaScript code, and the browser will execute it when it
arrives. Executing JSON-encoded data decodes it, but the result is still just data, and it doesn’t
do anything.

This is where the P part of the JSONP comes in. When invoked through the <script >
element, your service must “pad” its response with a prefix/padding function that will be called
to process the the response

["a","b","c",{
	"name":"coder"
}]

Now with padding

handleResponse([
	"a",
	"b",
	"c",
	{
	"name":"coder"
	}]);

	function getJSON(url, callback) {
		var counter = "cb" + getJSONP.counter++;
		var currentName = "getJSON." + counter;

		if (url.indexOf("?") === -1) {
			url += "?jsonp=" + currentName;
		} else {
			url += "&jsonp=" + currentName;
		}

		var script = document.createElement("script");

		getJSON[counter] = function(response) {
			try {
				callback(response);
			} finally {
				delete getJSON[counter];
				script.parentNode.removeChild(script);
			}
		};

		script.src = url;
		document.body.appendChild(script);
	}
	getJSONP.counter = 0;

Jul

27

Ajax and and HTTP Request, Cross-Origin Prt.7

The XMLHttpRequest object can issue request only to the server from which the document that uses it was downloaded. This restriction closes security hole, but it is heavy-handed and also prevents a number of legitimate uses for cross-origin request. You can use cross-origin URLs with <form/> and <iframe/> elements, and the browser will display the resulting cross-origin document. But because of the same origin policy the browser will not allow the original script to inspect the content of the cross-origin document.

With XMLHttpRequest, document contents are always exposed through the
responseText property, so the same-origin policy cannot allow XMLHttpRequest to make cross-origin request.

But on the other hand the <script/> element has never been subject to the same-origin policy :
it will download and execute any script, regardless of origin. This make the <script/> element a very attractive alternative to XMLHttpRequest.

XHR2 allow cross-origin request to websites that opt-in by sending appropriate CORS (Cross-Origin Resource Sharing) headers in their HTTP response.
CORS is a fare new feature and is only supported in a some of the latest browsers.
However if you browser you are using supports CORS for XMLHttpRequest and the website allows it, the same origin policy will be relaxed and your XMLHttpRequest request will work. see code bellow dynamic titles :

window.onload = function (){

	var supportsCORS = (new XMLHttpRequest()).withCredentials !== undefined;

	var links = document.getElementsByTagName('a');
	for (var i = 0 ; i < links.lenght; i++){
		var link = links[i];
		if(!link.href) continue;
		if(!links.tile) continue;

		if(link.host !== location.host || link.protocol !== location.protocol){

			link.title = "Off-site";
			if (!supportsCORS) continue;
		}

		if (link.addEventListener){
			link.addEventListener("onmuseover",mouseroverHandler,false);
		}else{

			link.attacheEvent("onmuseover",mouseroverHandler);
		}
	}
	function mouseoverhand(e){
		var link = e.target || e.srcElement;
		var url = link.href;

		var request = new XMLHttpRequest();
		request.open("HEAD", url);
		request.onreadystatechange = function (){
			if (request.readyState !== 4) return;
			if(request.status === 200) {
				var type = request.getResponseHeader("Content-type");
				var size = request.getResponseHeader("Content-Length");
				var date = request.getResponseHeader("Last-Modified");
				link.title = "Type:"+ type+"-Size:"+size+"-Date"+date;
			}else {
				if (!link.title){
					link.title = "No Title fetched";

				}
			}
		};
		request.send(null);

		if (link.removeEventListener){
			link.removeEventListener("onmuseover",mouseroverHandler,false);
		}else{

			link.detacheEvent("onmuseover",mouseroverHandler);
		}
	}
}

Jul

23

Ajax and and HTTP Request in Web Applications Prt.6

Decoding the response

In the previous post, we assume the server has sent a textual response, with a MIME type “text/plain”, or “text/css” and retrieved it with the responseText property of the XMLHttpRequest obect.

There are other ways to handle the server’s response, however. It the server sends an XML or XHTML document as its response, you can retrieve a parsed representation of the XML document through the responseXML property. the value of the property is a Document object, and you you can search and transverse it with native methods and properties

if the server wants to send structured data such as an object or array, as its response, it might transmit that data as a JSON-encode string. Whwn you receive it, you would then pass the responseText property to JSON.parse();

function get(url,callback) {
	var request = XMLHttpRequest();
	request.open("GET",url);
	request.onreadystatechange = function () {

		if ( request.readyState === 4 && request.status === 200) {
			var type = request.getResponseHeader("Content-Type");
			if(type.indexOf("xml") !== -1 && request.responseXML){
				callback(request.responseXML);
			}else if (type  == "application/json"){
				callback(JSON.parse(request.responseText));
			}else {
				callback(request.responseText);
			}
		}
	};
	request.send(null);
}

Jul

22

Ajax and and HTTP Request in Web Applications Prt.5

Synchronous response

By their very nature, HTTP response are best handled asynchronously. Nevertheless, XMLHttpRequest also supports synchronous response. If you pass false as the third argument to open() the send() method will block until the request completes. In this case, there is no need to use an event handler: once send () returns, you can just check the status and the responseText properties of the XMLHttpRequest object. Compare this synchronous code gettextData() in part 4

gettextDataSync(url){
	var request = new XMLHttpRequest();
	request.open("GET",url,false);
	if(request.status !== 200) throw new Error(request.statusText);

	var type = request.getResponseHeader("Content-Type");
	if(!type.match(/^text/))
		throw new Error("Expected textual response; got : " + type);
	return request.responseText;
}

Synchronous request are tempting, but they should be avoided. Client side javasScript
is single threaded and when the send() method blocks, it typically freezes the entire browser UI. if the server you are connecting to is responding slowly, your user’s browser will freezeup.


Images Resources