Understand Ajax XMLHttpRequest in details - javascript

I am new to Ajax, and to make things worse, also a Javascript noob, and I have posted the bellow code of a chat script, to retrieve text from db, in real time, and the code is working, but I need to understand what certain requests are all about.
<script>
function retrieve(){
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest(); }
else if(window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
else {
alert('Please update your browser to start chatting');
}
Simply, I understand the above is (I created it) just a function with global variable declared to be assigned whether XMLHttpRequest/ActiveXObject Object is declared depending if browser is IE6,7 and others if not throw in alert...
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("canvas").innerHTML = xmlhttp.responseText;
}
}
Similarly, the above I assume takes the onreadystatechange property of the Ajax API and checks for it's state, readyState & status which, if only they match 4 and 200 means, Ajax is working as wanted
t = setTimeout("retrieve()", 2000);
I know the setTimeout() is a bit like setInterval() function, which runs the function inside it, every 2 seconds, to check for new messages.
xmlhttp.open("GET", "getajax.php", true);
xmlhttp.send();
Now, the problem is with the above, I can almost understand that the .open method is supposed to get data from getajax.php even though, I have no idea of what true means in this instance, but as far as the xmlhttp.send(); I have absolutely no clue,
So, All I need is for you to explain to me what I have missed during my illaboration, and
what the last queries mean, just in brief.
}
retrieve();
</script>
<div id="canvas"></div>

xmlhttp.open("GET", "getajax.php", true);
xmlhttp.send();
true is what tells the request to be performed A -synchronously, which is the A in AJAX. Then finally .send() actually send the request.
Asynchronous requests are non-blocking meaning that the rest of your code wont wait for them to finish and return before continuing. That is why you sent event handlers before starting the request via xmlhttp.onreadystatechange. That way once the request is complete you have already told your script what to do with the returned information.
Hope this helps.
Edit Additionally I recommend using some sort of framework or library for javascript like jQuery. While it is good to learn some of the javascript core, something like jQuery will make your life much easier.

Simply, I understand the above is (I created it) just a function with global variable declared to be assigned
xmlhttp isn't a global. It's a local variable in the global function retrieve.
Similarly, the above I assume takes the onreadystatechange property of the Ajax API and checks for it's state
onreadystatechange is a property that accepts a function. That function is run when the value of readyState changes. That function is usually used to check the status of the request.
I know the setTimeout() is a bit like setInterval() function, which runs the function inside it, every 2 seconds, to check for new messages.
setTimeout is like setInterval in a sense that it runs a function at a later time. Unlike setInterval, it only runs the code once. Also, that's not the proper way of running a timer. Here's a post that explains how to properly use timers.
the .open method is supposed to get data from getajax.php even though, I have no idea of what true means in this instance, but as far as the xmlhttp.send(); I have absolutely no clue
The open builds your request by accepting:
The type of request (GET/POST)
The url where you want the request sent
The third argument determines if the request is asynchronous or not.
If set to false, this makes the request synchronous. The browser will freeze and wait for the response.
If true, the request us asynchronous. The browser will not freeze in waiting.
The default value is true, so you can omit it.
send is the actual function that ultimately sends the request to the server.
For further reading, I suggest you read MDN's section regarding AJAX.

Related

Detect when an AJAX request starts

Following the spec I've been given for this particular item, I have a few dozen AJAX requests all initiated at the same time, and the results displayed as they complete to give responses as soon as possible.
Currently I have all of the items show as "Loading...", then gradually getting replaced as the requests complete.
Due to limitations placed by the browser, only about five of them actually load at any given time, the others are blocked until earlier ones have completed.
I'd like to know if there's any way of finding out when the block ends and the request is actually sent.
Initial tests using onreadystatechange to detect readyState values other than 4 are not promising - no event is fired until it's complete, at which point I get 2, 3 and 4 in immediate succession (note that for testing, the AJAX responses are artificially delayed by usleeping for a random time)
Any ideas? Or is my only real option to manually implement the blocking part?
The best approximation of this you can actually get is to watch for readyState "1".. which signifies the server connection has been established. This will give you a pretty close estimation as to when the connection actually went live.
I've hacked up at http://jsfiddle.net/r0gknr3w/. Just watch the JS console, and you'll see "1" logged. You say you never saw a readyState 1... but it's definitely there.
var xhr = $.ajax({
url: "/echo/html",
xhr: function () {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
console.log(xhr.readyState);
}
return xhr;
}
});
Can you use jquery function to call ajax request.It is better to send multiple request parallel and response get as soon as..

Where or where to refresh the view?

I have a MySQL form with a drag 'n drop hot spot, and several image tags. The data field is simply a char(100) that stores a link to the uploaded image file. With each image tag I have a button to delete the image. It in turn calls a confirm dialog, and if confirmed calls a Javascript function to delete the image. The Javascript function calls a separate PHP file that executes the update to the MySQL table. What I would like to do is refresh the view once all this has been executed. I have searched all over Google, and this site and have tried numerous versions of everything claimed to work. But so far, I have found nothing. I don't want to use a meta tag because I found that that if you are attempting to upload an image invariably it would refresh before you can complete the upload.
As it is, everything works fine, except for the timing to execute a refresh. I'm assuming and logically it would seem that once the PHP update function has completed that that would be the time to execute a refresh. But so far, I haven't been able to get a Javascipt refresh function to work from an external PHP. It also seems that from the initial Javascipt function that it doesn't wait for the PHP to finish before calling a refresh from there. In other words, like these last few lines:
ajaxRequest.open("GET", "AjaxDeleteImage.php" + queryString, true);
ajaxRequest.send(null);
//window.location.reload(true);
Where you can see I commented out the reload. I tried it there, but it just killed everything. I would be happy to include more code if needed. Maybe my method is too convoluted and someone can give me a swift kick if needed.
AJAX calls are asynchronous so once the request goes out, the rest of the script carries on executing. This is generally a good thing otherwise your page will hang until the AJAX is done.
To carry out an action when the AJAX request is finished, you need to assign a callback function. This will be run when the AJAX is done. Or more accurately when the AJAX request state changes.
I lifted this from W3Schools:
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//refresh page here or do other cool stuff
}
}
In your case you would change xmlhttp to ajaxRequest.
The onreadystatechange property expects a function and this function will be called whenever the state of the AJAX request changes. There are 5 different states, but the one you're interested in is 4 as this is the "I'm done!" state. The function above checks for this state and also checks the http status code returned from the server. If it is 200 life is good and you can then do what you need to do. The callback should be declared before calling .send().
You may also check for other status codes and react accordingly (say pop up an error if there is a 404 or 500 status code, or reset the page to a known good state so the user can try again).
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//refresh page here or do other cool stuff
}
elseif (xmlhttp.readyState==4 && xmlhttp.status==500)
{
//uh oh, something went wrong. Call Batman!
}
}
As an aside, libraries such as JQuery wrap up AJAX functionality into some very easy to use functions. A simple JQuery example:
$.get('myurl.php')
.done(function() {
alert( "success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});
As you can see, you can perform your GET request and define all your handlers in one easy statement. If you only care about success, you can shorten it to just:
$.get('myurl.php', function(){
alert('success');
});

Javascript block on AJAX load

I am looking for a way to make an AJAX load request in javascript, but have the javascript code pause execution while waiting for the AJAX load to complete. In other words, I am trying to do a synchronous AJAX load request (I know the 'A' in AJAX stands for asynchronous. I'm just hoping maybe the name isn't exactly right.) . What I have is
$('#my_id').load("my_page.pl?my_param=p1&my_other_param=p2");
//Please wait here
//Now do stuff after load is complete.
The reason I want the request to be synchronous is because it creates an HTML table, and then the javascript which follows parses the table.
jQuery's 'load()' method takes a callback. Callbacks are generally how async code handles the "waiting" feature you want.
$("#my_id").load("my_page.pl?my_param=p1&my_other_param=p2", function (response) {
// do this stuff, which will run after the request is complete
});
That looks like jquery... I can't be sure because I don't know jquery at all but if so you might get better answers tagging it as such.
I can tell you that javascript has it's own method for synchronous OR asynchronous calls. This is what I use:
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
// Use the activeX object for old IE
xmlhttp.open("GET","http://some.internet.address/woot?foo=bar", false);
// The third argument in the open function determines the asynchronous nature,
//it was set to false, so the code will halt at the send() point while the request is executed.
xmlhttp.send();
// Now, if the call succeeded...
if (xmlhttp.status==200) {
response = eval('('+xmlhttp.responseText+')');
// ...save the results to an object named response...
}
else {
// ...Otherwise do some other stuff
errorFunction(xmlhttp.status);
}
Lots of good info is also available here -
http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp

Can someone explain to me what this JavaScript/Ajax part of code does?

I'm learning Ajax and I'm going through this example. What does this do? I don't understand the syntax variable = function(){ how is a function being assigned to a variable?
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
I know everyone is saying it's a callback specifically but the question you asked could better be answered by comparing what you're puzzled over with some more familiar code.
function myFunction()
{
...
}
So we know that calling myFunction() will run that code.
In Javascript, you can declare a function in a number of ways. This means that this:
var myFunction = function()
{
...
}
Does exactly the same as the first example above. It creates a function that you can call using myFunction().
Add the callback into the mix in your question and we can see that
xmlhttp.onreadystatechange = function()
{
...
}
is nothing more than assigning a function and containing code to the onreadystatechange property of object xmlhttp. Meaning that your code within the function will be called every time there is a state change in the xmlhttp object.
When readyState changes, if request finished and response is ready (readyState==4) and document loaded correctly (HTTP Status Code 200 = OK!), append response text to the element with id #txtHint.
onreadystatechange stores a function (or the name of a function) to be called automatically each time the readyState property changes.
readyState holds the status of the XMLHttpRequest. Changes from 0 to 4:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
status takes HTTP response codes:
200: "OK"
404: Page not found
onreadystatechange is a callback. It gets triggered when a particular event happens. onreadystate is happens when the requests ready state changes.
In short onreadystate
Stores a function (or the reference of a function) to be called automatically each time the readyState property changes
Now for the line
xmlhttp.readyState==4 && xmlhttp.status==200
readyState : Holds the status of the XMLHttpRequest.
Changes from 0 to 4:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
And status Holds status
200: "OK"
404: Page not found
So xmlhttp.readyState==4 && xmlhttp.status==200 condition is true when the response is ready and there is no issues
xmlhttp.responseText contains the response sent from the server.
So document.getElementById("txtHint").innerHTML=xmlhttp.responseText; changes the HTML of the element with id txtHint to the response that was received.
Hope all the above made sense!!!
I'd like to address this comment: I've never been able to understand callbacks.
Consider this analogy:
You need want to rent that movie that just came out on VHS, so you
call Blockbuster and ask the attendant if they have a copy. Sadly
though, they are super busy dealing with thousands of David Bowie fans
who are trying to rent "Labyrinth" all at the same time and he does't
have time to look up the information for you. So instead, he asks for
your phone number. At some point in the future when the hordes of
people have left and he has the time, he looks up the info you need,
and calls you back on the number you provided. Turns out the movie is
sold out though, so he suggests "Dark Crystal" instead.
In your case you are dealing with an entity that is going to take a long time to do it's work as it needs to talk to remote servers, so it essentially asks you for your phone number so that when it's done you are called back as it were, with the requested data.
Does it make more sense now?

Two xmlHttpRequests in a single page

I'm fairly new to ajax but am trying to implement two simple calls to dynamically changes two separate divs on a page using javascript. I have no problems using one call at a time, but when I use two it seems like the second xmlhttprequest takes over the first and writes into both divs.
I've read and tried using the fixes listed on these two other posts both neither seem to work in my case:
Sending two Ajax requests to two different PHP scripts from single javascript function
Using two xmlhttprequest calls on a page
And here is my relevant code:
function request_handler(url, params, changed_div) {
if(window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
}catch(e) {
req = false;
}
}else if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
req = false;
}
}
}
if(req) {
req.onreadystatechange = function(){
if (req.readyState == 4 && req.status == 200){
document.getElementById(changed_div).innerHTML = req.responseText);
}
}
req.open("POST", url, true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send(params)
return true;
}
return false;
}
Here is the basic format of each request using the function above:
request_handler("sample.php", parameters , "sample_div");
Apologies if I'm passing something simple up here, I just can't seem to get it to work.
This question
Using two xmlhttprequest calls on a page
does answer your question.
In your request_handler function, you're using a global variable req that gets overwritten every time you call that function.
If you change it to start:
function request_handler(url, params, changed_div) {
var req;
// Rest of your function
}
you should find that it works. In this case req has a local scope and so is not overwritten when you call request_handler for the second time.
Can I also suggest that you strongly consider using the likes of jQuery, Prototype or Dojo, if you're planning on writing Ajax scripts? Writing scripts that work cross-browsers is hard to do well and these frameworks do a lot of the legwork for you.
Your req is a global variable as it is defined without the var keyword, keep that in mind.
What I think happens is that the second call overwrites the first one. This is because of the (default) asynchronous nature of the XMLHTTPRequest. Your first function call will end, but the fetching of the page is still going. The second function call then overwrites the previous request.
This however does not explain why both div get filled with the result of the second call. I must say I'm a bit lost on that one.
This is a pretty common problem, especially if you don't want to take additional measures to block further calls until the first has finished loading. Its a bigger subject that I can cover in a post but there are several examples on the web of an "Ajax Queue" that effectively manages the order of requests received.
jQuery has a plugin for managing queues and I'm certain that most other JavaScript frameworks such as Prototype and MooTools will as well. If you're wanting to stick with raw JavaScript I would take a look at this web page:
http://www.cmarshall.net/MySoftware/ajax/index.html
He implements a queue very effectively and has an excellent example of its use.

Categories

Resources