Asynchronous HTTP Requests

XHR

a long time ago...

 in an internet tube not so far away

In the early 1990s Web Pages were static

 

Each time the browser reloaded a page because of a partial change, all of the content had to be re-sent, even though only some of the information had changed.

First a little history

First a little history (cont.)

  • In 1996, the <iframe> tag was introduced by Internet Explorer to load or to fetch content asynchronously.
  • In 1998, Microsoft Outlook Web App team implemented the first component XMLHTTP by client script.
  • In 1999, Microsoft used its iframe technology to dynamically update the news stories and stock quotes on the default page for Internet Explorer,[5] and created the XMLHTTP ActiveX control in Internet Explorer 5, which was later adopted by MozillaSafariOpera and other browsers as the XMLHttpRequest JavaScript object.

You probably know its other name

The Term AJAX was first stated in this article.

GMAIL (2004) and GOOGLE MAPS (2005) were one of the first large scale web applications to make use of AJAX requests.

Then came AJAX

AJAX stands for Asynchronous Javascript and XML

You will see XML in the wild but most applications today use JSON as the suggested format for data interchange.

Then came AJAX (cont.)

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
</catalog>
</xml>

"XML BE LIKE..."

Then came AJAX (cont.)

{
    "catalog": [
        {
            "id": "bk101"
            "author": "Gambardella, Mattew",
            "title": "XML Developer's Guide",
            "genre": "Computer",
            "price": "44.95",
            "publish_date": "2000-10-01",
            "description": "An in-depth look at creating applications with XML."
        },
        {
            "id": "bk102"
            "author": "Ralls, Kim",
            "title": "Midnight Rain",
            "genre": "Fantasy",
            "price": "5.95",
            "publish_date": "2000-12-06",
            "description": "A former architect battles corporate zombies, an evil sorceress, 
                            and her own childhood to become queen of the world."
        }
    ]
}

"JSON BE LIKE..."

{
    "catalog": [
        {
            "id": "bk101"
            "author": "Gambardella, Mattew",
            "title": "XML Developer's Guide",
            "genre": "Computer",
            "price": "44.95",
            "publish_date": "2000-10-01",
            "description": "An in-depth look at creating applications with XML."
        },
        {
            "id": "bk102"
            "author": "Ralls, Kim",
            "title": "Midnight Rain",
            "genre": "Fantasy",
            "price": "5.95",
            "publish_date": "2000-12-06",
            "description": "A former architect battles corporate zombies, an evil sorceress, 
                            and her own childhood to become queen of the world."
        }
    ]
}
<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
</catalog>
</xml>

Pros and Cons

Advantages of JSON

  • Smaller message size
  • More structural information in the document
    • Can easily distinguish between the number 1 and the string "1" as numbers, strings (and Booleans) are represented differently in JSON.
    • Can easily distinguish between single items and collections of size one (using JSON arrays).
  • Easier to represent a null value
  • Easily consumed by JavaScript

Pros and Cons

Advantages of XML

  • Namespaces allow for sharing of standard structures
  • Better representation for inheritance
  • Standard ways of expressing the structure of the document: XML schema, DTD, etc
  • Parsing standards: DOM, SAX, StAX
  • Standards for querying: XQuery and XPath
  • Standards for transforming a document: XSLT

Pros and Cons

Draw

  • Human Readable
  • Easy to parse

How it works

How it works (cont.)

same concept, different diagram

Client-side app

Server-side app 

Server-side app 

Building with XHR

with vanilla javascript (no libraries)

Javascript (vanilla)

var oReq = new XMLHttpRequest();

Instantiate a new XHR object

function reqListener () {
  console.log(this.responseText);
}

Declare a function to be used as the event listener.

oReq.addEventListener("load", reqListener);

Attach the event listener to an event

oReq.open("GET", "http://www.google.com");
oReq.send();

Set the destination and send the request!

function reqListener () {
  console.log(this.responseText);
}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.google.com");
oReq.send();

the code

oReq.addEventListener("load", reqListener);

Wheres the asynchronous part?

After you invoke .send() javascript sends the request and waits for a response.

function reqListener () {
  console.log(this.responseText);
}

The response is a data stream and once the download is complete your event listener will trigger

var oReq = new XMLHttpRequest();

oReq.addEventListener("progress", updateProgress);

oReq.addEventListener("load", transferComplete);

oReq.addEventListener("error", transferFailed);

oReq.addEventListener("abort", transferCanceled);

oReq.send();

Events

you can set the events after you call .open() but before you call .send()

oAjaxReq.setRequestHeader(DOMString header, DOMString value);

method signature


oAjaxReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

real example #1


oAjaxReq.setRequestHeader('Origin', 'http://www.example-social-network.com');

real example #2

you can set the headers after you call .open() but before you call .send()

this.response;

available to you on `this` inside of your event listener

Returns an ArrayBufferBlobDocument, JavaScript object, or a DOMString, depending of the value of XMLHttpRequest.responseType.

this.responseText;

Returns a DOMString that contains the response to the request as text, or null if the request was unsuccessful or has not yet been sent.

this.responseType;

Properties (cont.)

available to you as `this` inside of your event listener

"" DOMString (this is the default value)
"arraybuffer" ArrayBuffer
"blob" Blob
"document" Document
"json" JavaScript object, parsed from a JSON string returned by the server
"text" DOMString
this.status;

Properties (cont.)

available to you as `this` inside of your event listener

Status of the response of the request. This is the HTTP result code

(i.e, 200 stands for a successful request).

XMLHttpRequest.statusText;

Returns a DOMString containing the response string returned by the HTTP server. Unlike XMLHTTPRequest.status, this includes the entire text of the response message ("200 OK", for example).

HTTP Request Methods

Lets talk a little about HTTP requests: GET and POST

What is HTTP?

HTTP

The Hypertext Transfer Protocol is designed to enable communications between clients and servers.

 

HTTP works as a request-response protocol between a client and server.

 

A web browser may be the client, and an application on a computer that hosts a web site may be the server.

Example: A client (browser) submits an HTTP request to the server; then the server returns a response to the client. The response contains status information about the request and may also contain the requested content.

HTTP METHODS CRASH COURSE

  • GET - "I WANT DATA"
  • POST - "I HAVE DATA TO SEND"
  • PUT - "I HAVE DATA I WANT TO CHANGE"
  • DELETE - "I WANT TO REMOVE DATA"

You could use jQuery

Check browser support:

http://caniuse.com/#feat=fetch

Fetch API is nice because it returns a Promise.

One thing to remember is that Promises are "then-ables" e.g. `.then()`


Promise(/* url goes here, maybe options */)
    .then(function(response) {
        //             ^
        //             |                        
        // DEFINE A PARAMETER
        // whenever this asynchronous operates ends
        // data will be passed to you here.

        return 'something to be used in the next .then()'
    })
    .then(function(dataFromAbove) {
       // do something will data
    })
    .catch(function(error){
        // all errors within the .then() above or during the asynchronous operation
        // will fall through and get caught here
    });

FETCH - GET


fetch('http://swapi.co/api/people/1')
    .then(function(response) {
      console.log(response);
      return response.json();
    })
    .then(function(jsonData) {
      console.log(jsonData);
      let para = document.createElement('p');
      para.innerHTML = jsonData.name;
      dynamicDataContainer.appendChild(para);
    })
    .catch(function(error) {
      console.log('Something went wrong!');
      console.log(error);
    });

GET requests just need a URL

FETCH - POST

var requestOptions = {
    headers: new Headers({
      'Content-Type': 'application/json'
    }),
    method: 'POST',
    mode: 'cors',
    body: JSON.stringify({
      title: 'Hard times for a pug',
      author: 'Ray Farias'
    })
  };

  var request = new Request(urlDataEndpoint, requestOptions);

  fetch(request)
    .then(function(response) {
      console.log(response);
      return response.json();
    })
    .then(function(jsonData) {
      lastIdCreated = jsonData.id;
      console.log('lastIdCreated: ', lastIdCreated);
    })
    .catch(function(error) {
      console.log('Something went wrong!');
      console.log(error);
    });

needs a little more setup but with the new FETCH API it looks a lot more like the conventions you see in Javascript than an alien language

FETCH

supports other HTTP Methods

  • PUT
  • DELETE

 

(more references beneath this slide)

FETCH API REFERENCES

Cross-origin resource sharing (CORS)

A resource makes a cross-origin HTTP request when it requests a resource from a different domain than the one which served itself.

 

For example, an HTML page served from http://domain-a.com makes an <img> src request for http://domain-b.com/image.jpg. Many pages on the web today load resources like CSS stylesheets, images and scripts from separate domains.

 

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts.  For example, XMLHttpRequest follows the same-origin policy. So, a web application using XMLHttpRequest could only make HTTP requests to its own domain. To improve web applications, developers asked browser vendors to allow XMLHttpRequest to make cross-domain requests.

References

XMLHttpRequest

By Ray Farias

XMLHttpRequest

  • 4,403