Web Tool Bag
Home · Articles · Downloads · Discussion Forum · Web Links · News Categories · Hosting information · Hosting ArticlesJanuary 06 2009 19:36:16
Navigation
Home
Articles
Downloads
Discussion Forum
Web Links
News Categories
Contact Me
Search
Site Partners
Users Online
Guests Online: 1
No Members Online

Registered Members: 125
Newest Member: Walter_Rowbotham36c41
viagra joke download us licensed pharmacies ketamine valium phentermine discount on-line no prescription best generic ultram cheap phentermine and xanax ambien long term side effects tramadol medication weight loss medicine meridia buy line viagra where danger of ambien cialis with purple pill paxil cr tablets paxil cr online from dreampharmaceuticals phentermine 37.5mg 90 pills ativan and flexeril tramadol serotonin dopamine buy cheap valium tramadol 58 93 generic phentermine india order ultram with out a prescription buy cheap discounted tramadol 20mg of ambien pharm phentermine buying viagra uk tramadol and flushed feeling order ambien from canada cheap phentermine about cheap phentermine mexico pharmacy ambien weight loss meridia lorazepam anxiety attack sleep insomnia picture of the pill viagra cheap cheap deal pill viagra viagra perscription drug stores ultram tramadol cheap ambien no prescription klonopin vers xanax can ambien cause a stroke zovirax pills pfizer sildenafil viagra counterfeit lorazepam effect phentermine 30mg blue no prescription viagra pulminary hypertension sildenafil citrate lowest cheap phentermine with no physician approval drug know maker need xanax ambien and breast pain tramadol detect urinalysis side effects of ultram free shipping on tramadol orders tramadol diazepam no prior prescription overnight delivery lunesta vs ambien soft pill cialis online and phentermine and cod pharmacy degree line buy tramadol cheap cod fedex tramadol very wellbutrin adhd phentermine sold without a prescription generic finasteride propecia order tadalafil and online fluconazole and alprazolam green white capsules phentermine phentermine drug indications buy xanax cheap medic affect phentermine side online pharmacy diflucan and clonazepam celecoxib and mesothelioma anaerobic infection atrophic rhinitis zithromax cod prozac cheap prednisone muscle weakness my fioricet fiorcet migraine is ambien gluten free cialis fee online cheapest xanax online female viagra alternate what is soma the drug nextday tramadol cash on deliver cod generic viagra money order weight loss and celexa withdrawal viagra online pharmacies glucophage help ovulation ambien as a date rape drug tramadol and kidneys weight glucophage hrt phentermine discount 30 mg phentermine 2737 amerimedrx herpes nexium zyban meridia better than phentermine meridia xenical and phentermine where to buy viagra ativan off re phentermine prescription viagra dosage 100mg cialis consultation delivery discount health man wellbutrin and lorazepam viagra sale pharmacy online cheap viagra new zealand buy xanax online us pharmacy picture of phentermine 37.5 12.5 ambien cr drug generic online pharmacy wellbutrin zyban wellbutrin information sildenafil viagra tablets bei hf6rsturz sildenafil viagra no presrciption what generic xanax look like lorazepam trip by glucophage generic equivalent of ambien lorazepam ld50 crushing tramadol for quick release cash on delivery fioricet mp 58 soma ambien sulfa diazepam no prescription next day delivery does ambien increase testosterone soma cubes phentermine scripts online herbal supplement contains sildenafil citrate adipex effects harmful side xanax grapefruit juice interaction phentermine hpen fen no dr required buring levitra online viagra baby what is best viagra cialis overnight phentermine no prescription hair loss and wellbutrin ambien bovine danger in using ambien viagra versus cialis espa ol viagra online canadiain effects of ambien on fetus what color is ambien acxess cialis usa mail buy sublingual cialis online sildenafil citrate us overnight delivery cheap phentermine 37.5mg buy tadalafil prescription medicine levitra duration of action ordering cheap phentermine cod cialis tadalafil canadian ultram more drug side effects metformin glucophage buy sildenafil citrate for sale online pharmacy overnight ativan 1mg finasteride propecia is tramadol a narcotic phentermine phentermine abuse eye from hemorrhage paxil phentermine and soma online pharmacy soma drug interaction tramadol seizures no script for cheap phentermine pliva tramadol buy keflex online can you get high on tramadol fosamax cancer splitting viagra 100 mg cheap online genric ambien buy evista cheap canada ambien levitra versus viagra tramadol as antidepressant search for fioricet when is valium perscribed ambien sleep pill atenolol fatigue generic meridia 10 mg discount hepsera hydrocodone soma wellbutrin allergic reaction pain medication tramadol fosamax weight loss side effects wellbutrin paxil valium accuretic ambien causing brain tumors add adult strattera vs wellbutrin appetite suppression drug sibutramine meridia phentermine levitra doseage order propecia pill atavan ativan tramadol drug guide order tadalafil canada online no rx cheap phentermine tramadol effects on dogs zoloft and valium together paxil or lexapro mix diazepam and vicoden avodart ciales clomid diflucan dostinex glucophage buy phentermine online without prescription cheap weight gain wellbutrin lexapro next day ambien adipex p lawsuits cialis the new viagra ativan withdrawl medical breakthrough of 1998 viagra diazepam experiment tramadol 100 er description id foreign phentermine pill sildenafil citrate tabletes buy phentermine costa rica buy viagra online in the uk viagra soft tabs next day buy xanax amex buy canadian prozac online danger levitra lexapro and xanax phentermine cod pharmacy online line tramadol cialis online from dreampharmaceuticals vrx v herbal viagra false positive for tramadol cheap soma usa tramadol and menstrual cycles tramadol cloridrato best herbal viagra viagra buy lamisil online generic cialis pills free sample tramadol and money order fluoxetine and norco fosamax weekly dose buy tramadol online pharmacy online online pharmacy phentermine xenical meridia ambien ativan klonopin dosage withdrawl detox diabetic diet vegetarian phentermine pill prescription drugs ambien free sample paxil and nursing buy xanax prescription require cheap phentermine through lighthouse phentermine yellow low dose prednisone low nexium price dysfunction erectile viagra alprazolam food effect valium stage fright interview generic viagra listings tramadol naproxin buy propecia online consultation lowest price tetracycline acne generic cialis soft viagra teddy bear phentermine no prescription 32 lorazepam for anxiety offender sex viagra buying viagra in canada ambien and price pharmacy online buy fioricet diazepam prilosec weight loss drugs phentermine clonazepam valium phentermine shipping celexa discount pharmacy purchase mixing ambien and vicodin cheap viagra pills buying phentermine without a prescription viagra online description chemistry ingredients sildenafil safe viagra alternatives switch from celexa to effexor ambien sleep talking find viagra free online search a buy phentermine online between difference levitra viagra glyburide metformin ambien online cheap phentermine discounts lexapro cause weight nexium delayed release capsule identify generic xanax phentermine free consultation no prescription addictive diazepam valium and alprazolam xanax fluoxetine hydrochloride as treatment information about danger of taking phentermine buy tramadol with paypal nexium online no prescription viagra and money order 5citrate generic sildenafil viagra 100 no prescription phentermine no topomax neurontin ritalin prozac ambien safe dose 5 sildenafil citrate warnings 67 flomax fluoxetine prescription writing for diazepam furosemide wellbutrin xl muscle relaxer drugs soma bontril xanax ambien day use cold sore valtrex mexican jumping bean viagra paxil pharmacy no prescription 1mg ativan vs xanax 0.5mg diazepam 2mg effects lowest price on phentermine 37.5 tetracycline antibiotic phentermine online overseas overnight express delivery generic cialis diet levitra ativan pdr diazepam drug information viagra perscription levitra drug cialis lawyer columbus ambien side effects tinnitus buy phentermine online u s pharmacy generic cialis pills doses discount online propecia lowest price phentermine gt can viagra delay ejaculation phentermine 37 5mg california ortho specialists newport beach ca buying phentermine with a money order tramadol recreational dose danger zithromax long term and liver viagra cll buy phentermine overnight online tramadol and depression meridia diet aie prednisone tablets side effects xanax xr generic ambien generic substitute soma discount code chicos generic ambien price crushing fosamax physical properties sildenafil citrate phentermine 90 pills no prescription buy tramadol where phentermine differences in pills info on tramadol living performance anxiety viagra propecia generic brand weight loss no prescription meridia western health levitra coverage tramadol 2bonline free tramadol delivery bontril ultram generic zanaflex cheap no prescription viagra order valium online drinking alcohol tramadol tramadol inducing withdrawl meridia cheap from india paxil pe online ambien zolpidem tartrate buy phentermine blue white capsuls online wellbutrin sr bupropion massachusetts christian cialis where can i buy phentermine cod synthroid more drug side effects xanax versus klonopin for chronic anxiety phentermine no prescription us pharmacy cheap ambien discount online pharmacy ambien table prednisone long term phentermine hcl diet pills dream online order pharmaceutical soma prevent effexor withdrawal with prozac discount valtrex fosamax 70 mg weekly phentermine hcl safe to take tramadol rls plmd iv iv sample viagra cheap evista online 6generic propecia alternative ambien cause numbness famvir buy prescription online valtrex viarga phentermine without prescription foreign online pharmacies lexapro xanax drug levitra viagra vs ambien rock opera mexican generic cialis trazadone and prozac interaction 180 cheap tramadol ativan drug interaction viagra erection attorneys dui ambien acyclovir 400 mg tablets order viagra buying viagra uk buy tetracycline no prescription valium shipped in u s fioricet drug phentermine tablets no rx buy phentermine online medipharm nexium discount permanent side effects ambien ambien and beer don't mix cut viagra pill ambien dose where can i buy cialis does herbal phentermine work gt generic overnight viagra pregnancy safety diazepam loss meridia pill weight switching from lexapro to zoloft online search tramadol cheap evista online cheap weight loss with paxil fda-approved prescribing ambien what type of medication is glucophage taking 5htp with prozac buy ambien without prescription information on cialis for erectile disfuntion ambien dreams online valium no prescriptions alternate uses for acyclovir tramadol drug medication tramadol cheap overnight inexpensive buy cialis dreampharmaceuticals online sildenafil chronic lung disease ambien shape buy viagra online u ambien cheapest paxil lawsuit canada plavix and cialis taken together what is metformin cheap adipex online cheap i us phentermine very buy fluoxetine hydrochloride india lorazepam seizure prophylaxis by dhl fioricet shipped overnight shipping phentermine without prescription phentermine 37.5 mg without primary doctor phentermine in stock overnight oxycontin taken with xanax sibutramine meridia and orlistat xenical generic viagra drugstore india lorazepam images diazepam manufacturer meridia buy without prescription phentermine 30mg without doctor prescription ambien side effects pulmonary tight chest ambien day next online drug soma manufacturer ultracet with aspirin lethal dose for lorazepam does it long paxil take work order viagra or levitra ambien yellow pills aciphex phentermine alprazolam online pharmacy cheap source viagra buy lexapro cheap ndice keflex oral soft tabs viagra canadian pharmacy for phentermine fentanyl patch and ultracet weight gain due to ambien lexapro more drug interactionslipitor dosage paxil lorazepam 1mg images pill splitter cialis glucophage tablets cheap genaric tramadol mix maxalt and valium cialis cost viagra pills online pharmacy 2b soma 100 mg tramadol what is chemical formula of tramadol no prior perscription tramadol health viagra woman ambien dangers tramadol drop drug tramadol ultram acid indigestion tramadol wetrack it fioricet 40 mg discount buy cialis doctor online 90 pills phentermine under 100.00 is klonopin or xanax better cheap online sales viagra ativan and celexa reactions buy cialis tadalafil at horizon drugs levitra online prescription augmentin side effects generic xanax 5 picture 1 meridia online contraindications information overdose tramadol ultracet buy tramadol online meridia pharmacy what is fioricet butalbital apap generic cialis uk fluoxetine drug info 10 panel drug tests and alprazolam fosamax osteonecrosis ambien and expire help vicoden effexor soma lexapro buying viagra in the united kingdom generic celexa problems viagra free gratis soma medication in florida tramadol for sale without a presription buy phentermine from study trial erope paxil weight loss tips prednisone weaning 37.5 mg phentermine tab cheap tramadol cod cheap valium with no rx canadian pharmacy for viagra when did prozac go generic uk viagra supplier side effects to ambien phentermine us pharmacy consultation xanax lortab adipex impurity related substance viagra depakote with tramadol take phentermine with xen soma on line cheap 6 finax hair loss generic propecia order finasteride online order phentermine safe viagra woman ambien articles cheap deal deal pill viagra viagra best quality lowest prices generic viagra available wellbutrin zyban difference cheap celecoxib buy phentermine 37.5 mgs morphine tramadol dosage equivalent tramadol dog dose tramadol cheap overseas fosamax mice thyroid difference between niravam xanax and alprazolam prednisone side effects in cats deal free viagra viagra free consultation us prednisone side effects in dog ambien overdose amount cheap no phentermine prescription required online catalog buy phentermine buy cheap xenical ambien and sinus smell discount phentermine 100 viagra ans levitra risk chest pain atenolol bush valium images of phentermine diet pills cialis wholesale online nexium drug tramadol and gos phentermine phentermine successful stories online pharmacy pill soma u s viagra buying phentermine online us licensed pharmacies leathal dose ambien information phentermine shortage ambien class action law suit viagra femenino cheap phentermine for sale cheap gerneric viagra valium equivalents for lorazepam 92 accepted cod phentermine mood disorder nos and prozac diet pill phentermine 37.5 meridia 15mg buy cheap cheap phentermine shipped by fedex buy viagra $8 per pill xanax and hydrocodone tadalafil vs generic viagra pill tramadol 180 ct tramadol cod delivery diazepam medication sildenafil and steroid use ativan generic lorazepam online soma drug information school finance what is tramadol discounted adipex meridia drug interaction cheap 15mg of meridia is lorazepam a truth serum inventor of lorazepam wyeth no rx phentermine 37.5 90 150 fioricet dosage ambien looks like ambien skin crawling phentermine to order weaning from ambien female free sample viagra minoxidil propecia phentermine online pharmacy's snorted valium buy cheap free online viagra viagra osteoporosis fosamax glucosamine glucophage pregnancy dose prozac impotence pill viagra phentermine fast no prescription nexium online phentermine 37.5mg no perscription fioricet medicine coupons ativan online no prescription articles about ambien cr phentermine no prescription fed-ex day where to puchase cialis online diazepam makes me depressed chlorhydrate de tramadol ingredients in phentermine original phentermine no rx diazepam dose in dogs phentermine adipex no prescripton necessary klonopin review rating xanax adipex buy online phentermine xanax cheap mexico buy tadalafil medicine online ambien fibromyalgia taking xanax lamisil and zoloft drugs tramadol ultram online diazepam no prescription meridia success pain meds and viagra is generic propecia fda approved sibutramin and phentermine and orlistat canadian pharmacy cialis deals cheap viagra nz recreation use of tramadol diazepam and gaba buy lexapro news imprint codes for tramadol medication pill ambien cr how supplied generic cialis pills levitra cialis generic versus brand name side effects of evista and fortical order tadalafil mexico online diazepam ip but phentermine without prescription soma conference san diego cheap soma canada buy generic ambien online drug fosamax osteoporosis treatment diet drug manufacturer meridia order phentermine free consultation buy viagra ambien 2baddiction tramadol chlorhydrate supply price history of valium buy ambien cr no rx finasteride vs dutasteride for steroids famvir zovirax valtrex phentermine diet pills no precription required tadalafil cialis from india cialis bestellen soma 350 flexeril meridia 10mg buy descrition of ambien cr buy 37.5 phentermine ambien cr while pregnant celexa and pregnancy glucophage buy diazepam from us pharmacy lorazepam 1mg picture buy cheap fioricet prescription nexium side effects phentermine with no prescription needed metformin insulin resista side effects if tetracycline vs sumycin foreign pharmacy buy hydrocodone xanax diet phentermine pill official store ups next day air tramadol celexa side effects 5cheapest sildenafil citrate alprazolam buy or xanax tramadol cod 50 states best buy deal online viagra viagra action ambien class suit lorazepam long acting benzodiazepine tramadol lead investigator viagra on-line drug testing ultram interaction tramadol and dalmane can glucophage cause a delayed period nursing article on ativan are ambien and tylenol safe together herbal i viagra is levitra as good as viagra cheap cod online sold tramadol celexa order online ambien patent expired cheap online viagra viagra viagra ultracet tab does paxil cause weight loss cheap diazepam 32 dream online pharmaceutical propecia hypertension pulmonar y sildenafil order phentermine online without perscription pharmacy cialis silagra fioricet migraine treatment ativan or xanax diazepam valium fedex online lorazepam and pregnancy buy ambien overnight what does viagra pill look like lamina propecia buy tramadol cod synthroid effect of fasting blood glucose klonopin to replace ativan klonopin rating xanax hycrococone phentermine viagra online in united states tramadol consult ambien where to buy ambien ambulance picture of viagra bottle tramadol proper doses for dogs phentermine no prescription 90 day order phentermine ativan by phone calcium fosamax asthma prednisone fosamax and teeth phentermine education genuine ham percussor reflex viagra what does viagra do to females buy generic cialis uk fioricet delivery on saturday buy adipex without prescription phentermine u s online physician how to go off paxil cialis zestril interactions lorazepam discovery free levitra sample discount phentermine blue phentermine no prescription online wellbutrin xl online headaches and migraine tramadol buy sildenafil citrate rxonline cialis pharmacy paxil viagra patanol online drug stores metrogel buy phentermine without a doctor's prescription
Basic XMLHttpRequest

Basic XMLHttpRequest



I can't wait to share this new wonder, The people will all see its light, Let them all make their own music, The priests praise my name on this night.

-- Rush, Discovery

It's XMLHttpRequest that gives AJAX its true power: the ability to make asynchronous HTTP requests from the browser and pull down content in small chunks.

Web developers have been using tricks and hacks to achieve this for a long time, while suffering annoying limitations: the invisible iframe hack forced us to pass data back and forth between the parent document and the document in the iframe, and even the "remote scripting" method was limited to making GET requests to pages that contained JavaScript.

Modern AJAX techniques, which use XMLHttpRequest, provide a huge improvement over these kludgy methods, allowing your app to make both GET and POST requests without ever completely reloading the page.

In this chapter, we'll jump right in and build a simple AJAX web application -- a simple site-monitoring application that pings a page on a web server to a timed schedule. But before we start making the asynchronous HTTP requests to poll the server, we'll need to simplify the use of the XMLHttpRequest class by taking care of all of the little browser incompatibilities, such as the different ways XMLHttpRequest objects are instantiated, inside a single, reusable library of code.

A Simple AJAX Library

One approach to simplifying the use of the XMLHttpRequest class would be to use an existing library of code. Thanks to the increasing popularity of AJAX development, there are literally dozens of libraries, toolkits, and frameworks available that make XMLHttpRequest easier to use.

But, as the code for creating an instance of the XMLHttpRequest class is fairly simple, and the API for using it is easy to understand, we'll just write a very simple JavaScript library that takes care of the basic stuff we need.

Stepping through the process of creating your own library will ensure you know how the XMLHttpRequest class works, and will help you get more out of those other toolkits or libraries when you do decide to use them.

Starting our Ajax Class

We'll start by creating a basic class, called Ajax, in which we'll wrap the functionality of the XMLHttpRequest class.

I've Never done Object Oriented Programming in JavaScript -- Help!

In this section, we'll start to create classes and objects in JavaScript. If you've never done this before, don't worry -- it's quite simple as long as you know the basics of object oriented programming.

In JavaScript, we don't declare classes with complex syntax like we would in Java, C++ or one of the .NET languages; we simply write a constructor function to create an instance of the class. All we need to do is:

  • provide a constructor function -- the name of this function is the name of your class
  • add properties to the object that's being constructed using the keyword this, followed by a period and the name of the property
  • add methods to the object in the same way we'd add properties, using JavaScript's special function constructor syntax

Here's the code that creates a simple class called HelloWorld:

function HelloWorld() {
 this.message = 'Hello, world!';
 this.sayMessage = function() {
   window.alert(this.message);
 };
}

JavaScript's framework for object oriented programming is very lightweight, but functions surprisingly well once you get the hang of it. More advanced object oriented features, such as inheritance and polymorphism, aren't available in JavaScript, but these features are rarely needed on the client side in an AJAX application. The complex business logic for which these features are useful should always be on the web server, and accessed using the XMLHttpRequest class.

In this example, we create a class called HelloWorld with one property (message) and one method (sayMessage). To use this class, we simply call the constructor function, as shown below:

var hw = new HelloWorld();
hw.sayMessage();
hw.message = 'Goodbye';
hw.sayMessage();

Here, we create an instance of HelloWorld (called hw), then use this object to display two messages. The first time we call sayMessage, the default "Hello, world!" message is displayed. Then, after changing our object's message property to "Goodbye," we call sayMessage and "Goodbye" is displayed.

Don't worry if this doesn't make too much sense at the moment. As we progress through the building of our Ajax class, it will become clearer.

Here are the beginnings of our Ajax class's constructor function:

Example 2.1. ajax.js (excerpt)

function Ajax() {
 this.req = null;
 this.url = null;
 this.method = 'GET';
 this.async = true;
 this.status = null;
 this.statusText = '';
 this.postData = null;
 this.readyState = null;
 this.responseText = null;
 this.responseXML = null;
 this.handleResp = null;
 this.responseFormat = 'text', // 'text', 'xml', or 'object'
 this.mimeType = null;
}

This code just defines the properties we'll need in our Ajax class in order to work with XMLHttpRequest objects. Now, let's add some methods to our object. We need some functions that will set up an XMLHttpRequest object and tell it how to make requests for us.

Creating an XMLHttpRequest Object

First, we'll add an init method, which will create an XMLHttpRequest object for us. Unfortunately, XMLHttpRequest is implemented slightly differently in Firefox (in this book, whenever I explain how something works in Firefox, I'm referring to all Mozilla-based browsers, including Firefox, Mozilla, Camino, and SeaMonkey), Safari, and Opera than it was in Internet Explorer's original implementation (interestingly, Internet Explorer version 7 now supports the same interface as Firefox, which promises to simplify AJAX development in the future), so you'll have to try instantiating the object in a number of different ways if you're not targeting a specific browser. Firefox and Safari create XMLHttpRequest objects using a class called XMLHttpRequest, while Internet Explorer versions 6 and earlier use a special class called ActiveXObject that's built into Microsoft's scripting engine. Although these classes have different constructors, they behave in the same way.

Cross-browser Code

Fortunately, most modern browsers (Internet Explorer 6, Firefox 1.0, Safari 1.2, and Opera 8, or later versions of any of these browsers) adhere to web standards fairly well overall, so you won't have to do lots of browser-specific branching in your AJAX code.

This usually makes a browser-based AJAX application faster to develop and deploy cross-platform than a desktop application. As the power and capabilities available to AJAX applications increase, desktop applications offer fewer advantages from a user-interface perspective.

The init method looks like this:

Example 2.2. ajax.js (excerpt)

this.init = function() {
 if (!this.req) {
   try {
     // Try to create object for Firefox, Safari, IE7, etc.
     this.req = new XMLHttpRequest();
   }
   catch (e) {
     try {
       // Try to create object for later versions of IE.
       this.req = new ActiveXObject('MSXML2.XMLHTTP');
     }
     catch (e) {
       try {
         // Try to create object for early versions of IE.
         this.req = new ActiveXObject('Microsoft.XMLHTTP');
       }
       catch (e) {
         // Could not create an XMLHttpRequest object.
         return false;
       }
     }
   }
 }
 return this.req;
};

The init method goes through each possible way of creating an XMLHttpRequest object until it creates one successfully. This object is then returned to the calling function.

Degrading Gracefully

Maintaining compatibility with older browsers (by "older" I mean anything older than the "modern browsers" I mentioned in the previous note) requires a lot of extra code work, so it's vital to define which browsers your application should support.

If you know your application will receive significant traffic via older browsers that don't support the XMLHtmlRequest class (e.g., Internet Explorer 4 and earlier, Netscape 4 and earlier), you will need either to leave it out completely, or write your code so that it degrades gracefully. That means that instead of allowing your functionality simply to disappear in less-capable browsers, you code to ensure that users of those browsers receive something that's functionally equivalent, though perhaps in a less interactive or easy-to-use format.

It's also possible that your web site will attract users who browse with JavaScript disabled. If you want to cater to these users, you should provide an alternative, old-school interface by default, which you can then modify on-the-fly -- using JavaScript -- for modern browsers.

Sending a Request

We now have a method that creates an XMLHttpRequest. So let's write a function that uses it to make a request. We start the doReq method like this:

Example 2.3. ajax.js (excerpt)

this.doReq = function() {
 if (!this.init()) {
   alert('Could not create XMLHttpRequest object.');
   return;
 }
};

This first part of doReq calls init to create an instance of the XMLHttpRequest class, and displays a quick alert if it's not successful.

Setting Up the Request

Next, our code calls the open method on this.req -- our new instance of the XMLHttpRequest class -- to begin setting up the HTTP request:

Example 2.4. ajax.js (excerpt)

this.doReq = function() {
 if (!this.init()) {
   alert('Could not create XMLHttpRequest object.');
   return;
 }
 this.req.open(this.method, this.url, this.async);
};

The open method takes three parameters:

1. Method - This parameter identifies the type of HTTP request method we'll use. The most commonly used methods are GET and POST.

Methods are Case-sensitive

According to the HTTP specification (RFC 2616), the names of these request methods are case-sensitive. And since the methods described in the spec are defined as being all uppercase, you should always make sure you type the method in all uppercase letters.

2. URL - This parameter identifies the page being requested (or posted to if the method is POST).

Crossing Domains

Normal browser security settings will not allow you to send HTTP requests to another domain. For example, a page served from ajax.net would not be able to send a request to remotescripting.com unless the user had allowed such requests.

3. Asynchronous Flag - If this parameter is set to true, your JavaScript will continue to execute normally while waiting for a response to the request. As the state of the request changes, events are fired so that you can deal with the changing state of the request.

If you set the parameter to false, JavaScript execution will stop until the response comes back from the server. This approach has the advantage of being a little simpler than using a callback function, as you can start dealing with the response straight after you send the request in your code, but the big disadvantage is that your code pauses while the request is sent and processed on the server, and the response is received. As the ability to communicate with the server asynchronously is the whole point of an AJAX application, this should be set to true.

In our Ajax class, the method and async properties are initialized to reasonable defaults (GET and true), but you'll always have to set the target URL, of course.

Setting Up the onreadystatechange Event Handler

As the HTTP request is processed on the server, its progress is indicated by changes to the readyState property. This property is an integer that represents one of the following states, listed in order from the start of the request to its finish:

  • 0: uninitialized - open has not been called yet.
  • 1: loading - send has not been called yet.
  • 2: loaded - send has been called, but the response is not yet available.
  • 3: interactive - The response is being downloaded, and the responseText property holds partial data.
  • 4: completed - The response has been loaded and the request is completed.

An XMLHttpRequest object tells you about each change in state by firing a readystatechange event. In the handler for this event, check the readyState of the request, and when the request completes (i.e., when the readyState changes to 4), you can handle the server's response.

A basic outline for our Ajax code would look like this:

Example 2.5. ajax.js (excerpt)

this.doReq = function() {
 if (!this.init()) {
   alert('Could not create XMLHttpRequest object.');
   return;
 }
 this.req.open(this.method, this.url, this.async);
 var self = this; // Fix loss-of-scope in inner function
 this.req.onreadystatechange = function() {
   if (self.req.readyState == 4) {
     // Do stuff to handle response
   }
 };

};

We'll discuss how to "do stuff to handle response" in just a bit. For now, just keep in mind that you need to set up this event handler before the request is sent.

Sending the Request

Use the send method of the XMLHttpRequest class to start the HTTP request, like so:

Example 2.6. ajax.js (excerpt)

this.doReq = function() {
 if (!this.init()) {
   alert('Could not create XMLHttpRequest object.');
   return;
 }
 this.req.open(this.method, this.url, this.async);
 var self = this; // Fix loss-of-scope in inner function
 this.req.onreadystatechange = function() {
   if (self.req.readyState == 4) {
     // Do stuff to handle response
   }
 };
 this.req.send(this.postData);
};

The send method takes one parameter, which is used for POST data. When the request is a simple GET that doesn't pass any data to the server, like our current request, we set this parameter to null.

Loss of Scope and this

You may have noticed that onreadystatechange includes a weird-looking variable assignment:

Example 2.7. ajax.js (excerpt)

var self = this; // Fix loss-of-scope in inner function

This new variable, self, is the solution to a problem called "loss of scope" that's often experienced by JavaScript developers using asynchronous event handlers. Asynchronous event handlers are commonly used in conjunction with XMLHttpRequest, and with functions like setTimeout or setInterval.

The this keyword is used as shorthand in object-oriented JavaScript code to refer to "the current object." Here's a quick example -- a class called ScopeTest:

function ScopeTest() {
 this.message = 'Greetings from ScopeTest!';
 this.doTest = function() {
   alert(this.message);
 };
}
var test = new ScopeTest();
test.doTest();

This code will create an instance of the ScopeTest class, then call that object's doTest method, which will display the message "Greetings from ScopeTest!" Simple, right?

Now, let's add some simple XMLHttpRequest code to our ScopeTest class. We'll send a simple GET request for your web server's home page, and, when a response is received, we'll display the content of both this.message and self.message.

function ScopeTest() {
 this.message = 'Greetings from ScopeTest!';
 this.doTest = function() {
   // This will only work in Firefox, Opera and Safari.
   this.req = new XMLHttpRequest();
   this.req.open('GET', '/index.html', true);
   var self = this;
   this.req.onreadystatechange = function() {
     if (self.req.readyState == 4) {
       var result = 'self.message is ' + self.message;
       result += '\n';
       result += 'this.message is ' + this.message;
       alert(result);
     }
   }
   this.req.send(null);
 };
}
var test = new ScopeTest();
test.doTest();

So, what message is displayed? The answer is revealed in Figure 2.1.

We can see that self.message is the greeting message that we're expecting, but what's happened to this.message?

Using the keyword this is a convenient way to refer to "the object that's executing this code." But this has one small problem -- its meaning changes when it's called from outside the object. This is the result of something called execution context. All of the code inside the object runs in the same execution context, but code that's run from other objects -- such as event handlers -- runs in the calling object's execution context. What this means is that, when you're writing object-oriented JavaScript, you won't be able to use the this keyword to refer to the object in code for event handlers (like onreadystatechange above). This problem is called loss of scope.

If this concept isn't 100% clear to you yet, don't worry too much about it. We'll see an actual demonstration of this problem in the next chapter. In the meantime, just kind of keep in mind that if you see the variable self in code examples, it's been included to deal with a loss-of-scope problem.

Processing the Response

Now we're ready to write some code to handle the server's response to our HTTP request. Remember the "do stuff to handle response" comment that we left in the onreadystatechange event handler? We'll, it's time we wrote some code to do that stuff! The function needs to do three things:

  1. Figure out if the response is an error or not.
  2. Prepare the response in the desired format.
  3. Pass the response to the desired handler function.

Include the code below in the inner function of our Ajax class:

Example 2.8. ajax.js (excerpt)

this.req.onreadystatechange = function() {
 var resp = null;
 if (self.req.readyState == 4) {
   switch (self.responseFormat) {
     case 'text':
       resp = self.req.responseText;
       break;
     case 'xml':
       resp = self.req.responseXML;
       break;
     case 'object':
       resp = req;
       break;
   }
   if (self.req.status >= 200 && self.req.status <= 299) {
     self.handleResp(resp);
   }
   else {
     self.handleErr(resp);
   }
 }
};

When the response completes, a code indicating whether or not the request succeeded is returned in the status property of our XMLHttpRequest object. The status property contains the HTTP status code of the completed request. This could be code 404 if the requested page was missing, 500 if an error occurred in the server-side script, 200 if the request was successful, and so on. A full list of these codes is provided in the HTTP Specification (RFC 2616).

No Good with Numbers?

If you have trouble remembering the codes, don't worry: you can use the statusText property, which contains a short message that tells you a bit more detail about the error (e.g., "Not Found," "Internal Server Error," "OK").

Our Ajax class will be able to provide the response from the server in three different formats: as a normal JavaScript string, as an XML document object accessible via the W3C XML DOM, and as the actual XMLHttpRequest object that was used to make the request. These are controlled by the Ajax class's responseFormat property, which can be set to text, xml or object.

The content of the response can be accessed via two properties of our XMLHttpRequest object:

  • responseText - This property contains the response from the server as a normal string. In the case of an error, it will contain the web server's error page HTML. As long as a response is returned (that is, readyState becomes 4), this property will contain data, though it may not be what you expect.
  • responseXML - This property contains an XML document object. If the response is not XML, this property will be empty.

Our Ajax class initializes its responseFormat property to text, so by default, your response handler will be passed the content from the server as a JavaScript string. If you're working with XML content, you can change the responseFormat property to xml, which will pull out the XML document object instead.

There's one more option you can use if you want to get really fancy: you can return the actual XMLHttpRequest object itself to your handler function. This gives you direct access to things like the status and statusText properties, and might be useful in cases in which you want to treat particular classes of errors differently -- for example, completing extra logging in the case of 404 errors.

Setting the Correct Content-Type

Implementations of XMLHttpRequest in all major browsers require the HTTP response's Content-Type to be set properly in order for the response to be handled as XML. Well-formed XML, returned with a content type of text/xml (or application/xml, or even application/xhtml+xml), will properly populate the responseXML property of an XMLHttpRequest object; non-XML content types will result in values of null or undefined for that property.

However, Firefox, Safari, and Internet Explorer 7 provide a way around XMLHttpRequest's pickiness over XML documents: the overrideMimeType method of the XMLHttpRequest class. Our simple Ajax class hooks into this with the setMimeType method:

Example 2.9. ajax.js (excerpt)

this.setMimeType = function(mimeType) {
 this.mimeType = mimeType;
};

This method sets the mimeType property.

Then, in our doReq method, we simply call overrideMimeType inside a try ... catch block, like so:

Example 2.10. ajax.js (excerpt)

req.open(this.method, this.url, this.async);
if (this.mimeType) {
 try {
   req.overrideMimeType(this.mimeType);
 }
 catch (e) {
   // couldn't override MIME type  --  IE6 or Opera?
 }
}
var self = this; // Fix loss-of-scope in inner function

Being able to override Content-Type headers from uncooperative servers can be very important in environments in which you don't have control over both the front and back ends of your web application. This is especially true since many of today's apps access services and content from a lot of disparate domains or sources. However, as this technique won't work in Internet Explorer 6 or Opera 8, you may not find it suitable for use in your applications today.

Response Handler

According to the HTTP 1.1 specification, any response that has a code between 200 and 299 inclusive is a successful response.

The onreadystatechange event handler we've defined looks at the status property to get the status of the response. If the code is within the correct range for a successful response, the onreadystatechange event handler passes the response to the response handler method (which is set by the handleResp property).

The response handler will need to know what the response was, of course, so we'll pass it the response as a parameter. We'll see this process in action later, when we talk about the doGet method.

Since the handler method is user-defined, the code also does a cursory check to make sure the method has been set properly before it tries to execute the method.

Error Handler

If the status property indicates that there's an error with the request (i.e., it's outside the 200 to 299 code range), the server's response is passed to the error handler in the handleErr property. Our Ajax class already defines a reasonable default for the error handler, so we don't have to make sure it's defined before we call it.

The handleErr property points to a function that looks like this:

Example 2.11. ajax.js (excerpt)

this.handleErr = function() {
 var errorWin;
 try {
   errorWin = window.open('', 'errorWin');
   errorWin.document.body.innerHTML = this.responseText;
 }
 catch (e) {
   alert('An error occurred, but the error message cannot be '
     + 'displayed. This is probably because of your browser\'s '
     + 'pop-up blocker.\n'
     + 'Please allow pop-ups from this web site if you want to '
     + 'see the full error messages.\n'
     + '\n'
     + 'Status Code: ' + this.req.status + '\n'
     + 'Status Description: ' + this.req.statusText);
 }
};

This method checks to make sure that pop-ups are not blocked, then tries to display the full text of the server's error page content in a new browser window. This code uses a try ... catch block, so if users have blocked pop-ups, we can show them a cut-down version of the error message and tell them how to access a more detailed error message.

This is a decent default for starters, although you may want to show less information to the end-user -- it all depends on your level of paranoia. If you want to use your own custom error handler, you can use setHandlerErr like so:

Example 2.12. ajax.js (excerpt)

this.setHandlerErr = function(funcRef) {
 this.handleErr = funcRef;  
}

Or, the One True Handler

It's possible that you might want to use a single function to handle both successful responses and errors. setHandlerBoth, a convenience method in our Ajax class, sets this up easily for us:

Example 2.13. ajax.js (excerpt)

this.setHandlerBoth = function(funcRef) {
 this.handleResp = funcRef;
 this.handleErr = funcRef;
};

Any function that's passed as a parameter to setHandlerBoth will handle both successful responses and errors.

This setup might be useful to a user who sets your class's responseFormat property to object, which would cause the XMLHttpRequest object that's used to make the request -- rather than just the value of the responseText or responseXML properties -- to be passed to the response handler.

Aborting the Request

Sometimes, as you'll know from your own experience, a web page will take a very long time to load. Your web browser has a Stop button, but what about your Ajax class? This is where the abort method comes into play:

Example 2.14. ajax.js (excerpt)

this.abort = function() {
 if (this.req) {
   this.req.onreadystatechange = function() { };
   this.req.abort();
   this.req = null;
 }
};

This method changes the onreadystate event handler to an empty function, calls the abort method on your instance of the XMLHttpRequest class, then destroys the instance you've created. That way, any properties that have been set exclusively for the request that's being aborted are reset. Next time a request is made, the init method will be called and those properties will be reinitialized.

So, why do we need to change the onreadystate event handler? Many implementations of XMLHttpRequest will fire the onreadystate event once abort is called, to indicate that the request's state has been changed. What's worse is that those events come complete with a readyState of 4, which indicates that everything completed as expected (which is partly true, if you think about it: as soon as we call abort, everything should come to a stop and our instance of XMLHttpRequest should be ready to send another request, should we so desire). Obviously, we don't want our response handler to be invoked when we abort a request, so we remove the existing handler just before we call abort.

Wrapping it Up

Given the code we have so far, the Ajax class needs just two things in order to make a request:

  • a target URL
  • a handler function for the response

Let's provide a method called doGet to set both of these properties, and kick off the request:

Example 2.15. ajax.js (excerpt)

this.doGet = function(url, hand, format) {
 this.url = url;
 this.handleResp = hand;
 this.responseFormat = format || 'text';
 this.doReq();
};

You'll notice that, along with the two expected parameters, url and hand, the function has a third parameter: format. This is an optional parameter that allows us to change the format of the server response that's passed to the handler function.

If we don't pass in a value for format, the responseFormat property of the Ajax class will default to a value of text, which means your handler will be passed the value of the responseText property. You could, instead, pass xml or object as the format, which would change the parameter that's being passed to the response handler to an XML DOM or XMLHttpRequest object.

Example: a Simple Test Page

It's finally time to put everything we've learned together! Let's create an instance of this Ajax class, and use it to send a request and handle a response.

Now that our class's code is in a file called ajax.js, any web pages in which we want to use our Ajax class will need to include the Ajax code with a <script type="text/javascript" src="ajax.js" mce_src="ajax.js"> tag. Once our page has access to the Ajax code, we can create an Ajax object.

Example 2.16. ajaxtest.html (excerpt)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <meta http-equiv="Content-Type"
       content="text/html; charset=iso-8859-1" />
   <title>A Simple AJAX Test</title>
   <script type="text/javascript" src="ajax.js" mce_src="ajax.js"></script>
   <script type="text/javascript">
     var ajax = new Ajax();
   </script>
 </head>
 <body>
 </body>
</html>

This script gives us a shiny, new instance of the Ajax class. Now, let's make it do something useful.

To make the most basic request with our Ajax class, we could do something like this:

Example 2.17. ajaxtest.html (excerpt)

<script type="text/javascript">
 var hand = function(str) {
   alert(str);
 }
 var ajax = new Ajax();
 ajax.doGet('/fakeserver.php', hand);
</script>

This creates an instance of our Ajax class that will make a simple GET request to a page called fakeserver.php, and pass the result back as text to the hand function. If fakeserver.php returned an XML document that you wanted to use, you could do so like this:

Example 2.18. ajaxtest.html (excerpt)

<script type="text/javascript">
 var hand = function(str) {
   // Do XML stuff here
 }
 var ajax = new Ajax();
 ajax.doGet('/fakeserver.php', hand);
</script>

You would want to make absolutely sure in this case that somepage.php was really serving valid XML and that its Content-Type HTTP response header was set to text/xml (or something else that was appropriate).

Creating the Page

Now that we have created the Ajax object, and set up a simple handler function for the request, it's time to put our code into action.

The Fake Server Page

In the code above, you can see that the target URL for the request is set to a page called fakeserver.php. To use this demonstration code, you'll need to serve both ajaxtest.html and fakeserver.php from the same PHP-enabled web server. You can do this from an IIS web server with some simple ASP, too. The fake server page is a super-simple page that simulates the varying response time of a web server using the PHP code below:

Example 2.19. fakeserver.php

<?php
header('Content-Type: text/plain');
sleep(rand(3, 12));
print 'ok';
?>

That's all this little scrap of code does: it waits somewhere between three and 12 seconds, then prints ok.

The fakeserver.php code sets the Content-Type header of the response to text/plain. Depending on the content of the page you pass back, you might choose another Content-Type for your response. For example, if you're passing an XML document back to the caller, you would naturally want to use text/xml.

This works just as well in ASP, although some features (such as sleep) are not as easily available, as the code below illustrates:

Example 2.20. fakeserver.asp

<%
Response.ContentType = "text/plain"
' There is no equivalent to sleep in ASP.
Response.Write "ok"
%>

Throughout this book, all of our server-side examples will be written in PHP, although they could just as easily be written in ASP, ASP.NET, Java, Perl, or just about any language that can serve content through a web server.

Use the setMimeType Method

Imagine that you have a response that you know contains a valid XML document that you want to parse as XML, but the server insists on serving it to you as text/plain. You can force that response to be parsed as XML in Firefox and Safari by adding an extra call to setMimeType, like so:

var ajax = new Ajax();
ajax.setMimeType('text/xml');
ajax.doGet('/fakeserver.php', hand, 'xml');

Naturally, you should use this approach only when you're certain that the response from the server will be valid XML, and you can be sure that the browser is Firefox or Safari.

Example: a Simple AJAX App

Okay, so using the awesome power of AJAX to spawn a tiny little JavaScript alert box that reads "ok" is probably not exactly what you had in mind when you bought this book. Let's implement some changes to our example code that will make this XMLHttpRequest stuff a little more useful. At the same time, we'll create that simple monitoring application I mentioned at the start of this chapter. The app will ping a web site and report the time it takes to get a response back.

Laying the Foundations

We'll start off with a simple HTML document that links to two JavaScript files: ajax.js, which contains our library, and appmonitor1.js, which will contain the code for our application.

Example 2.21. appmonitor1.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <meta http-equiv="Content-Type"
       content="text/html; charset=iso-8859-1" />
   <title>App Monitor</title>
   <script type="text/javascript" src="ajax.js" mce_src="ajax.js"></script>
   <script type="text/javascript" src="appmonitor1.js" mce_src="appmonitor1.js"></script>
 </head>
 <body>
   <div id="pollDiv"></div>
 </body>
</html>

You'll notice that there's virtually no content in the body of the page -- there's just a single div element. This is fairly typical of web apps that rely on AJAX functions. Often, much of the content of AJAX apps is created by JavaScript dynamically, so we usually see a lot less markup in the body of the page source than we would in a non-AJAX web application for which all the content was generated by the server. However, where AJAX is not an absolutely essential part of the application, a plain HTML version of the application should be provided.

We'll begin our appmonitor1.js file with some simple content that makes use of our Ajax class:

Example 2.22. appmonitor1.js (excerpt)

var start = 0;
var ajax = new Ajax();

var doPoll = function() {
 start = new Date();
 start = start.getTime();
 ajax.doGet('/fakeserver.php?start=' + start, showPoll);
}

window.onload = doPoll;

We'll use the start variable to record the time at which each request starts -- this figure will be used to calculate how long each request takes. We make start a global variable so that we don't have to gum up the works of our Ajax class with extra code for timing requests -- we can set the value of start immediately before and after our calls to the Ajax object.

The ajax variable simply holds an instance of our Ajax class.

The doPoll function actually makes the HTTP requests using the Ajax class. You should recognize the call to the doGet method from our original test page.

Notice that we've added to the target URL a query string that has the start value as a parameter. We're not actually going to use this value on the server; we're just using it as a random value to deal with Internet Explorer's overzealous caching. IE caches all GET requests made with XMLHttpRequest, and one way of disabling that "feature" is to append a random value into a query string. The milliseconds value in start can double as that random value. An alternative to this approach is to use the setRequestHeader method of the XMLHttpRequest class to set the If-Modified-Since header on the request.

Finally, we kick everything off by attaching doPoll to the window.onload event.

Handling the Result with showPoll

The second parameter we pass to doGet tells the Ajax class to pass responses to the function showPoll. Here's the code for that function:

Example 2.23. appmonitor1.js (excerpt)

var showPoll = function(str) {
 var pollResult = '';
 var diff = 0;
 var end = new Date();
 if (str == 'ok') {
   end = end.getTime();
   diff = (end - start) / 1000;
   pollResult = 'Server response time: ' + diff + ' seconds';
 }
 else {
   pollResult = 'Request failed.';
 }
 printResult(pollResult);
 var pollHand = setTimeout(doPoll, 15000);
}

This is all pretty simple: the function expects a single parameter, which should be the string ok returned from fakeserver.php if everything goes as expected. If the response is correct, the code does the quick calculations needed to figure out how long the response took, and creates a message that contains the result. It passes that message to pollResult for display.

In this very simple implementation, anything other than the expected response results in a fairly terse and unhelpful message: Request failed. We'll make our handling of error conditions more robust when we upgrade this app in the next chapter.

Once pollResult is set, it's passed to the printResult function:

Example 2.24. appmonitor1.js (excerpt)

function printResult(str) {
 var pollDiv = document.getElementById('pollDiv');
 if (pollDiv.firstChild) {
   pollDiv.removeChild(pollDiv.firstChild);
 }
 pollDiv.appendChild(document.createTextNode(str));
}

The printResult function displays the message that was sent from showPoll inside the lone div in the page.

Note the test in the code above, which is used to see whether our div has any child nodes. This checks for the existence of any text nodes, which could include text that we added to this div in previous iterations, or the text that was contained inside the div in the page markup, and then removes them. If you don't remove existing text nodes, the code will simply append the new result to the page as a new text node: you'll display a long string of text to which more text is continually being appended.

Why Not Use innerHTML?

You could simply update the innerHTML property of the div, like so:

document.getElementById('pollDiv').innerHTML = str;

The innerHTML property is not a web standard, but all the major browsers support it. And, as you can see from the fact that it's a single line of code (as compared with the four lines needed for DOM methods), sometimes it's just easier to use than the DOM methods. Neither way of displaying content on your page is inherently better.

In some cases, you may end up choosing a method based on the differences in rendering speeds of these two approaches (innerHTML can be faster than DOM methods). In other cases, you may base your decision on the clarity of the code, or even on personal taste.

Starting the Process Over Again

Finally, showPoll starts the entire process over by scheduling a call to the original doPoll function in 15 seconds time using setTimeout, as shown below:

Example 2.25. appmonitor1.js (excerpt)

var pollHand = setTimeout(doPoll, 15000);

The fact that the code continuously invokes the doPoll function means that once the page loads, the HTTP requests polling the fakeserver.php page will continue to do so until that page is closed. The pollHand variable is the interval ID that allows you to keep track of the pending operation, and cancel it using clearTimeout.

The first parameter of the setTimeout call, doPoll, is a pointer to the main function of the application; the second represents the length of time, in seconds, that must elapse between requests.

Full Example Code

Here's all the code from our first trial run with this simple monitoring application.

Example 2.26. appmonitor1.js

var start = 0;
var ajax = new Ajax();

var doPoll = function() {
 start = new Date();
 start = start.getTime();
 ajax.doGet('/fakeserver.php?start=' + start, showPoll);
}

window.onload = doPoll;

var showPoll = function(str) {
 var pollResult = '';
 var diff = 0;
 var end = new Date();
 if (str == 'ok') {
   end = end.getTime();
   diff = (end - start)/1000;
   pollResult = 'Server response time: ' + diff + ' seconds';
 }
 else {
   pollResult = 'Request failed.';
 }
 printResult(pollResult);
 var pollHand = setTimeout(doPoll, 15000);
}

function printResult(str) {
 var pollDiv = document.getElementById('pollDiv');
 if (pollDiv.firstChild) {
   pollDiv.removeChild(pollDiv.firstChild);
 }
 pollDiv.appendChild(document.createTextNode(str));
}

In a bid to follow good software engineering principles, I've separated the JavaScript code from the markup, and put them in two different files.

Further Reading

Here are some online resources that will help you learn more about the techniques and concepts in this chapter.

JavaScript's Object Model


Check out these two chapters on objects from the Client-Side JavaScript Guide for version 1.3 of JavaScript, hosted by Sun Microsystems. The first chapter explains all the basic concepts you need to understand how to work with objects in JavaScript. The second goes into more depth about JavaScript's prototype-based inheritance model, allowing you to leverage more of the power of object-oriented coding with JavaScript.

This is a brief introduction to creating private instance variables with JavaScript objects. It will help you get a deeper understanding of JavaScript's prototype-based inheritance scheme.

XMLHttpRequest

Here's a good reference page from the Apple Developer Connection. It gives a nice overview of the XMLHttpRequest class, and a reference table of its methods and properties.

This article, originally posted in 2002, continues to be updated with new information. It includes information on making HEAD requests (instead of just GET or POST), as well as JavaScript Object Notation (JSON), and SOAP.

This is XULPlanet's exhaustive reference on the XMLHttpRequest implementation in Firefox.

Here's another nice overview, which also shows some of the lesser-used methods of the XMLHttpRequest object, such as overrideMimeType, setRequestHeader, and getResponseHeader. Again, this reference is focused on implementation in Firefox.

This is Microsoft's documentation on MSDN of its implementation of XMLHttpRequest.


SIMPLE Ajax example

HTML page

This is the HTML page with three JavaScript functions that perform the XMLHttpRequest and subsequent update to the HTML page. (These are Ajax calls)

<html>

<head>

<title>Simple Ajax Example</title>

<script language="Javascript">

function xmlhttpPost(strURL) {

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);

}

}

self.xmlHttpReq.send(getquerystring());

}

function getquerystring() {

var form = document.forms['f1'];

var word = form.word.value;

qstr = 'w=' + escape(word); // NOTE: no '?' before querystring

return qstr;

}

function updatepage(str){

document.getElementById("result").innerHTML = str;

}

</script>

</head>

<form name="f1">

<p>word: <input name="word" type="text">

<input value="Go" type="button" onclick='JavaScript:xmlhttpPost("/cgi-bin/simple-ajax-example.cgi")'></p>

<div id="result"></div>

</form>

</body>

</html>

CGI Script

This is the CGI script that the JavaScript in the HTML page calls. This CGI script could just as easily be written in Python, Ruby, PHP etc.

#!/usr/bin/perl -w use CGI;  










$query = new CGI;
$secretword = $query->param('w');
$remotehost = $query->remote_host();













print $query->header;
print "<p>he secret word is <b>$secretword</b> and your IP is <b>$remotehost</b>.</p>";



Posted by zdravko on January 10 2007 08:59:25 971 Reads · Print
Ratings
Rating is available to Members only.

Please login or register to vote.

No Ratings have been Posted.
Login
Username

Password



Not a member yet?
Click here to register.

Forgotten your password?
Request a new one here.
Shoutbox
You must login to post a message.

godemo
15/11/2008 04:56
A demo for Simple Feedback ZDR would be nice

dot
29/07/2008 21:23
hey can anyone help me here with how to link Submit button to a thank you page

dolarat
10/03/2008 12:17
hey all

konv
21/02/2008 04:19
i may be in the wrong place but here goes ,i want to learn about shell/severs .as i am having problems staying connected to a irc chay room because of major lag from their saever any help would be app

Copyright © 2008 - www.webtoolbag.com