Tag Archives: AJAX

Using POST method in XMLHTTPRequest(Ajax)

19 Jan

Usually only the GET method is used while creating Ajax apps. But there are several occasions when POST is necessary when creating a ajax request. This could be for several reasons. For example, POST request are considered more secure than GET request as creating a POST request is relatively harder than creating a GET request.

Requirements

  • Create a XMLHTTPRequest Object that uses the POST method.
  • See if the arguments passed to it appear in the ‘$_POST‘ array in PHP.

Code

XMLHTTPRequest Object

For the sake of simplicity, we are going to create the XMLHTTPRequest object using the Firefox supported ‘ XMLHttpRequest()’ function. I believe that you know the proper way of creating a cross-browser XMLHttpRequest object. If not, learn that first.

var http = new XMLHttpRequest();

Using GET method

Now we open a connection using the GET method.


var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("GET", url+"?"+params, true);
http.onreadystatechange = function() {//Call a function when the state changes.
	if(http.readyState == 4 && http.status == 200) {
		alert(http.responseText);
	}
}
http.send(null);

I really hope that this much is clear for you – I am assuming that you know a bit of Ajax coding. If you don’t, please read a ajax tutorial that explains these parts before continuing.

POST method

We are going to make some modifications so POST method will be used when sending the request…


var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);

//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

http.onreadystatechange = function() {//Call a function when the state changes.
	if(http.readyState == 4 && http.status == 200) {
		alert(http.responseText);
	}
}
http.send(params);

The first change(and the most obvious one) is that I changed the first argument of the open function from GET to POST. Also notice the difference in the second argument – in the GET method, we send the parameters along with the url separated by a ‘?’ character…

http.open("GET",url+"?"+params, true);

But in the POST method we will use just the url as the second argument. We will send the parameters later.

http.open("POST", url, true);

Some http headers must be set along with any POST request. So we set them in these lines…

http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

With the above lines we are basically saying that the data send is in the format of a form submission. We also give the length of the parameters we are sending.

http.onreadystatechange = function() {//Call a function when the state changes.
	if(http.readyState == 4 && http.status == 200) {
		alert(http.responseText);
	}
}

We set a handler for the ‘ready state’ change event. This is the same handler we used for the GET method. You can use the http.responseText here – insert into a div using innerHTML(AHAH), eval it(JSON) or anything else.

http.send(params);

Finally, we send the parameters with the request. The given url is loaded only after this line is called. In the GET method, the parameter will be a null value. But in the POST method, the data to be send will be send as the argument of the send function. The params variable was declared in the second line as “lorem=ipsum&name=binny” – so we send two parameters – ‘lorem’ and ‘name’ with the values ‘ipsum’ and ‘binny’ respectively.

That’s it. If you wish to see the working of this script, I have set up a demo page for Ajax using post.

Libraries

The above given methods are the manual way of doing things – you can automate this using the hundreds of Ajax libraries out there.

jx


jx.load("get_data.php?lorem=ipsum&name=binny",handlerFunction,"text","POST");

Prototype

var myAjax = new Ajax.Request('get_data.php?lorem=ipsum&name=binny',{
	method: 'post',
	onComplete:handlerFunction
});

Dojo Toolkit

dojo.io.bind({
	url:        "get_data.php?lorem=ipsum&name=binny",
	mimetype:   "text/plain",
	method:		"POST",
	load:handlerFunction
});

Advertisements

Update Multiple Page Elements Using The XMLHTTPRequest Object and JavaScript

19 Jan

In the development of Ajax application many times we will encounter following issues.

  • The requiremnt to update multiple text boxes simultaneously.
  • Fill more that one dropdown list.
  • Update a combination of text boxes, dropdown lists and div tags.
  • Call different web pages and different webservices at the same time.

Imagine the case of a financial data site (such as a stock market info site) with various regions of the page used for displaying data any taking user inputs. We may want to populate fill numerous div tags, textboxes and dropdown lists with real time data. If we loop the several requests and we will also have to check for timeout, if timeout occurs and no data is returned, then we will have to fire the same request again. It may end up that we have made 10 requests and 4-5 requests simply timeout because of network problems. If we dont loop then we will either get whole data or nothing (in which case there is only one more request to be made).

In this article we will discuss the XMLHTTPRequest object and JavaScript and develop a JavaScript class which can asychronously update multiple HTML elements. Also this class can be extended as per the requirements. I have used ASP.NET as the platform in this example but it does as the solution is just Javascript it can be applied to any web development platform.

Regarding classes in JavaScript, technically there is no ‘class’ in JavaScript but we can use a function as a class.

Consider the following code :

function testClass()
{
this.Msg = “Hello”;
this.showMsg = function()
{
alert(this.Msg);
}
}

var obj = new testClass();
obj.Msg = “HI”;
obj.showMsg();

In above script if we remove obj.Msg = “HI”; we will get an alert with text Hello.

We will now develop our JavaScript class step-by-step:

  1. Include JS file and add the following code:

function AjaxClass()
{
this.Method = “GET”;//OR “POST”
this.Async = true; //OR false (asynchronous or synchronous call)
this.request = null;
this.init = function()
{
if (window.XMLHttpRequest) // if Mozilla, Safari etc
this.request = new XMLHttpRequest();
else if (window.ActiveXObject)
{ // if IE
try
{
this.request = new    ActiveXObject(“Msxml2.XMLHTTP”);
}
catch (e)
{
try
{
this.request = new ActiveXObject(“Microsoft.XMLHTTP”);
}
catch (e){}
}
}

if(this.request)
{
this.request.onreadystatechange=this.handleResponse;
//we will develope this.handleResponse function in step 3
this.request.open(this.Method, this.url , this.Async);
this.request.send(null);
}
}
}

Here we have created an XMLHTTPRequest object which is simply used to send a call to the server. The default method is GET (this.Method = “GET”) and calling type is Ascynchronous (this.Async = true)

  1. In this step we will develop simple logic which will allow us to dynamically call Ajax function created in Step 1.

For this one JSON (http://www.json.org/) object as follows.

this.JSONArray = {  “Method” : “POST”, //Method type
“Async”  : true, //Call type
“CallPage” : “CallPage.aspx”, //page or webservice
“Querystring” : “”, //Query string
“dependentType” : null,//[0,1,2,3] for isEdit
“isEdit”: [
{
“textBoxId” : null, //0 then this element
“dropDownId” : null, //1 then this element
“default” : null, //2 then this element
“misc”:null //3 then this element
}
]

};

In above script we can set the default values for all elements. We will use these values to set response from the server to textboxes,drop down lists,Div tags, td tags etc. Using “CallPage” : “CallPage.aspx” we can define default server page and while calling Ajax function we can change this value to web method or to any other web page.
As we will proceed in this article we will examine how to change all the above values and how can we use it to update multiple elements.Also we will see that how to extend the class.

  1. Recall from Step 1 : this.request.onreadystatechange = this.handleResponse;

In this step we will develop this.handleResponse function and in this function we will use the JSON object defined in Step 2. Whenever this.handleResponse function gets called script loses the focus of  this. To keep track of this object we will asign it to some variable. i.e var self = this; // To lose of focus of the element

In this function we will be able to receive data from server. Once we receive the data we can manipulate it. This function will handle the responses from web services as well as from web pages. The web service always returns a response in the form of XML whereas the response from the webpage can be any format defined by web developer.

The function will be as follows:

var self = this; // To handle lose of focus
this.handleResponse = function()
{
if(self.request.readyState == 4 && self.request.status == 200)
{
if (window.ActiveXObject) // for IE
{
var doc=new ActiveXObject(“Microsoft.XMLDOM”);
doc.async=”false”;
doc.loadXML(self.request.responseText);
}
// code for Mozilla, Firefox, Opera, etc.
else
{
var parser=new DOMParser();
var doc=parser.parseFromString(self.request.responseText,”text/xml”);
}
try
{
var data  = “”;
if(doc.documentElement) //Response from webservice
data = doc.documentElement.childNodes[0].nodeValue;
else data = self.request.responseText; //from web page
//data contains response text from the server

//At this point we have response from serve
//so here we will write our function to    //manipulate the data. We will develop it in
//4th step.
}
catch(e) {}
}

In the the 1st step we had:

if(this.request)
{
this.request.onreadystatechange=this.handleResponse;
this.request.open(this.Method, this.url , this.Async);
this.request.send(null);
}

We will now modify this so that we can directly use the JSON array which we defined in 2nd step:

if(this.request)
{
this.request.onreadystatechange=this.handleResponse;
this.request.open(this.JSONArray.Method, this.url , this.JSONArray.Async);
this.request.send(null);
}

While developing Ajax applications we ned to be aware of the following issues regarding domains:

  • URL for XMLHTTPRequest object should belong to same domain.
  • Firefox and other browser doesn’t allow cross domain communication.
  • IE will show warning for cross domain communication.

Thus our this.url = “http://myDomain/mysite/” + this.JSONArray.CallPage + this.JSONArray.Querystring;

e.g. “http://localhost/Demo/CallPage.aspx?”+this.JSONArray.Querystring;
Also whenever we want to call web methods like above example, we need to set following protocols under <webServices> in web.config file.

<webServices>
<protocols>
<add name=”HttpGet”/>
<add name=”HttpPost”/>
</protocols>
</webServices>

  1. Up to this point we have finished with development of the Ajax logic which will return a response. So now we need to develop logic for updating the HTML controls.

In this.handleResponse (step 3) we have seen that we get response in the “data” variable in JavaScript.

So now we have response from the server we will add following logic:

switch(self.JSONArray.dependentType)
{
case 0:
PopulateControls(self.JSONArray.isEdit[0].textBoxId,data);
//simple call to JS function
break;
case 1:
PopulateControls(self.JSONArray.isEdit[0].dropDownId,data);
break;
}


self.JSONArray.isEdit[0].textBoxId
will contain the id of the text box in which we need to update. And data is the response from the server. In our switch we have simply used the elements of JSON object developed in Step 2.

We will now focus on initiating a request and setting the elements of the JSON objects.

First simply create object of our AjaxClass().

var obj = new AjaxClass(); //Object creation
obj.JSONArray.Method = “GET”; //Setting Method
obj.JSONArray.isEdit[0].textBoxId=”txt1″;//Textboxid for response
obj.JSONArray.dependentType=0;//0->Textbox,1->drop downlist,
//2->tagId,3->Misc and so on
obj.init();//Initiate the AjaxCall

If obj.JSONArray.dependentType=1 then our switch case will not work for the textbox, but it will work for a dropdown list (check above switch case). This means we will have to set the dropdown in the JSON object:

obj.JSONArray.isEdit[0].dropDownId=”ddl1″;

In this way we can define our own set of HTML controls to be updated.

In the same way we can also change all the default settings in JSON object of that class.

e.g.

obj.JSONArray.Method = “GET”;
obj.JSONArray.CallPage = “Mywebservice/webMethod”;
obj.JSONArray.Querystring= “My querystring”;

For this URL will be : this.url = this.url + this.JSONArray.CallPage + this.JSONArray.Querystring ;

In case of a web service we will have to set the CallPage element as we did in the above example.

For multiple textboxes use: obj.JSONArray.isEdit[0].textBoxId=”txt1$txt2$txtn”;//$ is a delimiter
While sending data from the server send it with the same delimiter,in such a way when we split obj.JSONArray.isEdit[0].textBoxId and response data on $; we will receive data and the appropriate textBoxId.

Now that we have different types like “txtbox(es) + drop down list(s) + div” in such case we can use “misc” option of isEdit element of JSON object.

And we can define our  PopulateControls function the way we want. For ASP.NET we could also integrate ICallback logic for large data transfers.

You can download the demo code here . This contains an ASP.NET project with the following files:

  • XMLHTTPJsClass.js this file contains our AjaxClass() and funtion to populate textbox(es).
  • Demo.js this file contains 3 js function which initiates AjaxRequest with customization of  request. Here you can find web page and webservice calls.
  • Default.aspx page
  • Webservice.asmx page.