Drani Academy – Interview Question, Search Job, Tuitorials, Cheat Sheet, Project, eBook

Ajax

Tutorials – Ajax

 
Chapter 5: Using XMLHttpRequest

 

In the world of asynchronous web development, XMLHttpRequest (XHR) plays a pivotal role. It is the foundation upon which much of the modern web operates, enabling data retrieval and manipulation without the need for page refreshes. In this chapter, we will explore XMLHttpRequest in depth, discussing its features, usage, and best practices.


Understanding XMLHttpRequest

XMLHttpRequest, often referred to as XHR, is a JavaScript API that provides an easy way to make HTTP requests to a web server and retrieve data from it without requiring a full page reload. It was introduced in Internet Explorer 5 and later became a standard, supported by all major web browsers.

The XHR object enables you to perform various types of requests, including GET, POST, PUT, DELETE, and more, making it a versatile tool for sending and receiving data from a server. It can be used with various data formats, such as XML, JSON, HTML, and plain text.


Creating an XMLHttpRequest

To use XMLHttpRequest, you need to create an instance of the XHR object. This can be done using the new keyword in JavaScript. Here’s how to create an XHR object:

var xhr = new XMLHttpRequest();

Once you have an XHR object, you can configure it for your specific request.


Making a Simple GET Request

The most common use of XHR is to make GET requests to retrieve data from a server. Here’s a basic example of how to create and send a GET request using XHR:

var xhr = new XMLHttpRequest();

xhr.open(‘GET’, ‘https://api.example.com/data’, true);

xhr.onreadystatechange = function () {

  if (xhr.readyState === 4 && xhr.status === 200) {

    // Request was successful, and response is available in xhr.responseText

    var data = xhr.responseText;

    // Process and use the retrieved data

  }

};

xhr.send();

In this example:

  • We create an XHR object.
  • We use the open method to configure the request. The first parameter specifies the HTTP method (GET in this case), and the second parameter is the URL to the resource we want to retrieve. The third parameter, which is set to true, indicates that the request should be asynchronous.
  • We define an onreadystatechange event handler. This function is called when the XHR object’s state changes.
  • Inside the event handler, we check if the request is in the READYSTATE_COMPLETE state (value 4) and if the status is 200, indicating a successful response.
  • If the conditions are met, we retrieve the response data using xhr.responseText.

Sending Data with a POST Request

While GET requests are useful for fetching data, POST requests are used to send data to a server, often to update or create resources. Here’s how to make a POST request with XHR:

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/update', true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
var dataToSend = {
  key1: 'value1',
  key2: 'value2',
};
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    // Request was successful, and response is available in xhr.responseText
    var response = xhr.responseText;
    // Process and use the response
  }
};

xhr.send(JSON.stringify(dataToSend));

In this example:

  • We create an XHR object and use the open method to configure the request as a POST request.
  • We set the Content-Type header to indicate that we are sending JSON data.
  • We define the data to send as a JavaScript object (dataToSend).
  • Inside the onreadystatechange event handler, we check for a successful response.
  • We use xhr.send to send the data, converting it to a JSON string with JSON.stringify.


Handling Responses

Once the XHR request is complete, you need to handle the response. This typically involves checking the readyState and status properties of the XHR object to ensure the request was successful and then processing the response data. Here’s a breakdown of the readyState values:

  • 0: UNSENT – The XHR object has been created, but open has not been called yet.
  • 1: OPENED open has been called.
  • 2: HEADERS_RECEIVED – Headers have been received, and responseText is available.
  • 3: LOADING – Data is being downloaded. responseText contains some data.
  • 4: DONE – The request is complete, and the data is available in responseText.

For example, to check if the request is successful and process the response:

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // Request was successful, and response is available in xhr.responseText
      var response = xhr.responseText;
      // Process and use the response
    } else {
      // Handle errors or failed requests
    }
  }
};


Handling Errors

Handling errors and failed requests is an essential part of working with XHR. Errors can occur for various reasons, such as network issues or server problems. Here’s how you can handle errors:

xhr.onerror = function () {
  // An error occurred during the request
  console.error('An error occurred during the XHR request.');
};
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // Request was successful
      var response = xhr.responseText;
      // Process and use the response
    } else {
      // Handle non-200 status codes
      console.error('Request failed with status: ' + xhr.status);
    }
  }
};

In this example:

  • The onerror event is used to capture network errors.
  • Inside the onreadystatechange handler, we check for a non-200 status code and handle it accordingly.


Aborting Requests

Sometimes, you may need to cancel an ongoing XHR request, especially when making multiple requests or providing the user with the option to cancel a request. Here’s how to abort a request:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
// Abort the request after 5 seconds
setTimeout(function () {
  xhr.abort();
}, 5000);
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // Request was successful
      var response = xhr.responseText;
      // Process and use the response
    } else if (xhr.status === 0) {
      // Request was aborted
      console.warn('Request was aborted by the user or due to a timeout.');
    } else {
      // Handle other non-200 status codes
      console.error('Request failed with status: ' + xhr.status);
    }
  }
};
xhr.send();

In this example, we use the xhr.abort() method to cancel the request after a specified time.


Security and Same-Origin Policy

When making XHR requests, it’s crucial to understand the same-origin policy. This policy restricts web pages from making requests to a different domain (origin) than the one that served the web page. Cross-origin requests are typically blocked for security reasons.

To work around the same-origin policy, web developers often use techniques like JSONP (JSON with Padding) or CORS (Cross-Origin Resource Sharing). These techniques enable requests to be made to domains other than the one serving the web page. However, they come with their own security considerations and configuration requirements.


Using XMLHttpRequest Level 2

In addition to the original XMLHttpRequest, there’s a newer version called XMLHttpRequest Level 2, which introduces several enhancements. One notable feature is the ability to send and receive data in various formats, including FormData, Blob, and ArrayBuffer. It also provides a progress event for tracking the progress of uploads and downloads.

Here’s how to use XMLHttpRequest Level 2 to upload a file using FormData:

var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/upload', true);
var formData = new FormData();
var fileInput = document.querySelector('input[type="file"]');
formData.append('file', fileInput.files[0]);
xhr.send(formData);
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    // Request was successful, and response is available in xhr.responseText
    var response = xhr.responseText;
    // Process and use the response
  }
};

This example demonstrates how to use FormData to send a file to a server. The server can then process the file and return a response.


Best Practices

When working with XMLHttpRequest, consider the following best practices:

  1. Use Promises: To simplify the handling of asynchronous requests, consider using Promises or modern async/await syntax.
  2. Error Handling: Always implement error handling to gracefully handle network errors, timeouts, and non-200 status codes.
  3. Security: Be aware of the same-origin policy and the security implications of cross-origin requests. Use CORS or other techniques when necessary.
  4. Aborting Requests: Provide a way to cancel or abort ongoing requests, especially for long-running operations.
  5. Testing: Test your XHR-based functionality thoroughly to ensure it works as expected and handles errors gracefully.
  6. Security Headers: Consider including security headers in your responses, such as Content Security Policy (CSP), to protect your web application from potential security vulnerabilities.


Conclusion

XMLHttpRequest is a fundamental tool for making asynchronous requests in web development. It enables you to fetch data from a server, send data to a server, and handle responses. Understanding how to use XHR effectively is a valuable skill for any web developer. In the next chapter, we will explore more advanced topics in the world of Ajax, including working with different data formats, error handling, and interacting with third-party APIs.

Scroll to Top