why do we use setTimout function if AJAX is asynchronous? - javascript

I have been using jquery libraries for implementing AJAX. it was ok and I am comfortable with that. However, I started reading some ajax book and found the following code.
// stores the reference to the XMLHttpRequest object
var xmlHttp = createXmlHttpRequestObject();
// retrieves the XMLHttpRequest object
function createXmlHttpRequestObject()
{
// will store the reference to the XMLHttpRequest object
var xmlHttp;
// if running Internet Explorer
if(window.ActiveXObject)
{
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{
xmlHttp = false;
}
}// if running Mozilla or other browsers
else
{
try
{
xmlHttp = new XMLHttpRequest();
}
catch (e)
{
xmlHttp = false;
}
}
// return the created object or display an error message
if (!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
// make asynchronous HTTP request using the XMLHttpRequest object
function process()
{
// proceed only if the xmlHttp object isn't busy
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 0)
{
// retrieve the name typed by the user on the form
name = encodeURIComponent(document.getElementById("myName").value);
// execute the quickstart.php page from the server
xmlHttp.open("GET", "quickstart.php?name=" + name, true);
// define the method to handle server responses
xmlHttp.onreadystatechange = handleServerResponse;
// make the server request
xmlHttp.send(null);
}
else
// if the connection is busy, try again after one second
setTimeout('process()', 1000);
}
//executed automatically when a message is received from the server
function handleServerResponse()
{
// move forward only if the transaction has completed
if (xmlHttp.readyState == 4)
{
// status of 200 indicates the transaction completed successfully
if (xmlHttp.status == 200)
{
// extract the XML retrieved from the server
xmlResponse = xmlHttp.responseXML;
// obtain the document element (the root element) of the XML structure
xmlDocumentElement = xmlResponse.documentElement;
// get the text message, which is in the first child of
// the the document element
helloMessage = xmlDocumentElement.firstChild.data;
// update the client display using the data received from the server
document.getElementById("divMessage").innerHTML =
'<i>' + helloMessage + '</i>';
// restart sequence
setTimeout('process()', 1000);
}
// a HTTP status different than 200 signals an error
else
{
alert("There was a problem accessing the server: " + xmlHttp.statusText);
}
}
}
Here my question is why do we use setTimeout('process()', 1000); in handleServerResponse() function? Can't we do this without setTimeout('process()', 1000);?

For me, it looks like some kind of constant polling. It's reusing the AJAX request over and over every second, and when the previous request is still active, it waits another second to send it again. So it's not just create an AJAX request and deal with the response.
Using that code, the page would be updating constantly with the information retrieved from the server. Whenever server response has changed, page will as well but not in real time (only when next request finishes). It's similar to Periodic Refresh.
As an evolution, you can have Long Polling in which you spawn an AJAX request and then wait until server responds. If any info is there in the server for you, you'll receive the response immediately. If, while you are waiting for response, anything comes to the server for you, you will receive it. If your request times out, server will respond with an empty body. Then, your client will spawn another AJAX request. You can get some more info from the Wikipedia. Extra link: Comet.

In the given example , the book has call the process() function on the body onload event.
When I change the code to onload-> to onkeyup <input type="text" id="myName" onkeyup="process()"/> I could remove the code //setTimeout('process()', 1000);

Related

JavaScript POST Request Issue

So I'm creating a mobile application using Intel XDK, I am sending a JavaScript POST request of a username and password. I also did some research on the HTTP status codes and found this:
200 OK - Standard response for successful HTTP requests. The actual response will depend on the request method used. In a GET request, the response will contain an entity corresponding to the requested resource. In a POST request the response will contain an entity describing or containing the result of the action.
201 Created - The request has been fulfilled and resulted in a new resource being created.
202 Accepted - The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
So I would assume that when a new user is inserted through a POST request the status would be 201. However when I had this code:
XMLHTTP.onreadystatechange = function () {
if (XMLHTTP.status == 201) {
alert("User created.");
} else {
alert("Error!");
}
}
It would show the "Error!" and not "User created." But when I added this on to the code:
XMLHTTP.onreadystatechange = function () {
if (XMLHTTP.status == 201 || XMLHTTP.status == 200) {
alert("User created.");
} else {
alert("Error!");
}
}
It showed "User created." So I was wondering how come the status is 200 even though I'm sending a POST request to insert in to a database.
Secondly, it alerts the "User created." 4 times? Is that because it is in the function onreadystatechange so it changes each time and is alerted? If so I can I make it so that it only alerts one? Should I have an if statement wrapped in a setinterval as shown below:
setInterval(function () {
if (XMLHTTP.status == StatusNumberHere) {
alert("Blah");
}
}, 10);
Very few websites use those headers, your back-end probably just sends a 200 even though the request was successful in inserting data.
About your second question, the reason your alert is triggered four times is because onreadystatechanged is called four times, each with a different readyState:
Server connection established
request received
processing request
request finished and response is ready
So you probably want to add XMLHTTP.readyState === 4 to your if statement so it in the end becomes:
XMLHTTP.onreadystatechange = function () {
if (XMLHTTP.status === 200 && XMLHTTP.readyState === 4) {
alert("User created.");
} else {
alert("Error!");
}
}
The status returned is based on how the server decides to handle it, in most cased you will simply get a success (200), so there is no issue or abnormality with what you have done.
setInterval = hack, avoid at all costs unless implementing some actual interval function.
You can check the the readystate of the XMLHTTP request with
XMLHTTP.readyState == 4
to filter out only the completed event.
Here is a list of the ready state events:
http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp

Simple code for request url and show response code | javascript | jquery

How can to request url or website address and show response code with javascript or jquery?
i.e
request www.google.com
if (response_code = 200) {
print "website alive"
} else if (response_code = 204) {
print "not found";
}
I'm assuming from the jquery tag that you mean to do this in a browser, not from a server running NodeJS or similar (although there is a NodeJS module for jQuery).
Although you can request URLs and see the response code using the XMLHttpRequest object, the Same Origin Policy will prevent your accessing virtually any sites other than the one the page itself was loaded from. But if you're pinging the server your page was loaded from to make sure it's still there, you can do that:
function ping(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange;
xhr.open("get", url);
xhr.send();
function handleStateChange() {
if (xhr.readyState === 4) { // Request is complete
callback(xhr.status); // Tell the callback what the status code is
}
}
}

Send XHR request without receiving any data

I'm trying to make a very simple script that should keep me logged on a site, that deletes your session after 10 minutes of inactivity. This is quite simple, as follows:
//Silently "refresh" the page - at least server thinks you refreshed, thus you're active
function call() {
var req = new XMLHttpRequest();
//Load current url
req.open("GET",location.href,true);
//Try to only send the data! (does not work - the browser also receives data)
req.onprogress = function() {
this.abort(); //Abort request
wait(); //Wait another 5 minutes
}
//Repeat request instantly if it fails
req.onerror = call;
//Send
req.send();
}
function wait() {
//5minutes timeout
setTimeout(call,5000);
}
wait();
This works perfectly but the requests seem to load completely. Though the page is small, I want to make this clean and prevent downloading the data. This means, I want to stop loading just after the data starts downloading. Or better - after the data has been sent.
Is there a way to make such "ping" function?
I tried this code:
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
console.log( this.readyState );
if( this.readyState == 2 ) { //sent, otherwise it raises an error
console.log( 'aborting...' );
this.abort()
}
if( this.readyState == 4 ) {
console.log( this.responseText );
}
}
req.open( 'get', .... );
req.send();
prints:
1
2
aborting...
3
4
undefined
I am not completely sure with this, but I guess that by aborting the request aborts the download and retrieval of data, but all other states are triggered. I try this with a large image which was not cached and the request was done very quickly, without any result.
BTW. To just send a »ping« to your server you can also set the src of an image tag to the desired script, this will trigger the request too.

issue with XMLHttpRequest - returning status of 0 on local machine and live server

i am having trouble getting this XMLHttpRequest to work properly, this is my first time using ajax so i'm not sure if i'm formatting everything correctly. i have looked all over the web and i keep finding basically the same info and examples but certain elements are in different orders so i'm not sure which is correct and i've tried them all and nothing seems to work. here is my code:
function ajaxRequest(){
var activexmodes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]
if (window.XMLHttpRequest)
return new XMLHttpRequest()
else if (window.ActiveXObject){
for (var i=0; i<activexmodes.length; i++){
try{
return new ActiveXObject(activexmodes[i])
}
catch(e){
//suppress error
}
}
}
else
return false
}
function getData(fileName){
var fileLoc =encodeURI("assets/"+fileName+".html")
alert(fileLoc)
var request = new ajaxRequest()
request.open("GET",fileLoc,true)
var response = request.responseText
alert(request.status)
alert(response)
request.send(null)
return response
}
function home() {
var data = getData("home")
var contentDiv = document.getElementByClassName(content)
contentDiv.innerHTML = data;
}
home is triggered when the user clicks on a div in the page. i know that getData is being accessed because the alerts pop up, however i get a status code of 0, this happened on both my local machine and on a live server. i read that localhosts can throw a 0 status regardless of the actual status but its happening on a live server as well. if someone could help me fix this issue and/or clarify the correct order of events in the function i would greatly appreciate it.
EDIT:
new code:
function getData(fileName){
fileLoc = encodeURI("assets/"+fileName+".html")
alert(fileLoc);
request.onreadystatechange = processData;
request.open("GET",fileLoc, false);
request.send();
alert(request.readyState);
alert(response);
}
function processData(){
if (request.readyState==4){
if (request.status==200){
document.getElementsByClassName('content').innerHTML = request.responseText;
}
else{
alert("An error has occured making the request");
}
}
}
You are telling XMLHTTPRequest to send the request asynchronous, which means the rest of your script gets executed while you wait for the response. You will get a reponse code 0 (uninitialized) and an empty response, because at the time you return from the function that is the current status and response.
Instead you want to define a function to call when the state changes, or let XMLHTTPRequest work synchronous.
Please refer to this tutorial for a simple example that should help you out.

Having trouble reading Javascript code

I'm new in JS, and having quite hard time reading the following JS code.
The first parameter of the function is a url to a PHP script, the second is a string.
What confuses me is how to read code after the line:
self.xmlHttpReq.open('POST', strURL, true);
What happens after this? Which code should i look after this line? The script?
What happens after open?
function check_detail(strURL, pids)
{
var xmlHttpReq = false;
var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpReq.open('POST', strURL, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function()
{
if (self.xmlHttpReq.readyState == 4)
updatepage(self.xmlHttpReq.responseText, pids);
}
self.xmlHttpReq.send(getquery(pids));
}
The key is the call to "send()", which actually launches the HTTP request. That happens, but the code then proceeds immediately without waiting for the result.
When the server responds, the browser will invoke the anonymous function set up as the "readystatechange" handler. Exactly when that happens is unpredictable; it's asynchronous, in other words.
Thus, the "updatepage()" call will happen long after the "check_detail()" function has returned.
When you make an Ajax request (which is what you are doing here) it is asynchronous, which means that you don't know exactly when it will return so you can't just wait for the return.
Instead, you set up your function so that, when the request returns, a function is kicked off to handle the response. This is the onreadystatechange piece.
So the chronology will be: first the send() will occur, which will send the result of the getquery() method up to the PHP page. When that returns, the function defined within onreadystatechange will fire, which will call updatepage() and pass it both the text that was sent back from the Ajax call, and also the pids parameter.
If you're new to JavaScript, then I'd say it's a waste of time trying to figure out what's going on here - you're learning how to use the XHR object, how to make that cross-browser, and you're learning JavaScript at the same time.
I'd recommend doing the Ajax with a JavaScript library such as jQuery - don't try to learn it all now while you're learning JavaScript as well.
Most of that could be replaced with something along the lines of:
$.post(strURL, function (data) {
updatePage(data);
});
this is simple Ajax function
function check_detail(strURL, pids)
{
// definning new variable
var xmlHttpReq = false;
// creating variable self which will function as this
var self = this;
// creating HTTP request maker for Mozilla/Safari
if (window.XMLHttpRequest) {
self.xmlHttpReq = new XMLHttpRequest();
}
// creating HTTP request maker in IE
else if (window.ActiveXObject) {
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
// so this is the confusing part right ?
// xmlHttpReq.open opens connection tu the strURL and infomation sending method
// will be POST method ( other passible values can be GET method or even else )
self.xmlHttpReq.open('POST', strURL, true);
// this defines HTTP request header (small information about what we are sending)
// in fact this is sending Content-type of information
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// when HTTP request maker state will be changed for example:
// the data will be sent or data will be received this function will be fired
self.xmlHttpReq.onreadystatechange = function()
{
// readyState 4 means data has been received
if (self.xmlHttpReq.readyState == 4)
updatepage(self.xmlHttpReq.responseText, pids); // updatepage is user defined function
}
// this actually sends the HTTP request which is made above
// but don't be confused because of this code ordering
// I mean the function defining what to do when content will be received is implemented
// before sending HTTP request right ?
// thats because if the data is too small and internet is really fast HTTP query can be
// executed faster then defining new function which will cause javascript error
self.xmlHttpReq.send(getquery(pids));
}
hope this helps
if not
more about ajax: http://en.wikipedia.org/wiki/Ajax_(programming)

Categories