1. Introduction of AJAX

AJAX is Asynchronous JavaScript And XML. Through AJAX, asynchronous requests can be sent to the server in the browser. The biggest advantages are: == No refresh to get data ==. AJAX is not a new programming language, but a new way to use existing standards together.

2. AJAX features

2.1 the advantages of AJAX
  1. You can communicate with the server side without refreshing the page.
  2. Allows you to update parts of the page based on user events.
2.2 Disadvantages of AJAX
  1. Cannot rollback without browsing history
  2. Cross-domain problems exist (homologous)
  3. SEO is not friends

Use 3.

3.1 the XMLHttpRequest

All Ajax operations are done using XMLHttpRequest.

3.2 Preparing for the Server

Before using Ajax, you need to send requests to the server, so here you use the Express framework to create a server.js file to build a server. Since Ajax is subject to the same Origin policy by default, set the Access-Control-Allow-Origin response header on the server to resolve cross-domain problems (CORS cross-domain).

// server.js
const express = require('express')
// Create an application object
const app = express()
// Create a routing rule
app.get('/index'.(request, response) = > {
  // Set the response headers that are allowed across domains
  response.setHeader('Access-Control-Allow-Origin'.The '*')
  // Set the response body
  response.send('hello ajax')
})
app.post('/index'.(request, response) = > {
  response.setHeader('Access-Control-Allow-Origin'.The '*')
  response.send('post ajax')})// Listen on the port and start the service
app.listen(8282.() = > {
  console.log('Server started, listening on port 8000... ');
})
Copy the code

During the test, ensure that the server is enabled by running the node server.js command

3.3 Ajax Sending GET Requests

To prepare a HTML document, click on the button sends a request to the interface http://127.0.0.1:8282/index requested data display in a div

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Ajax get request</title>
  <style>
    .result{
      border: 1px solid black;
      width: 250px;
      height: 150px;
    }
  </style>
  
</head>
<body>
  <button>Send the request</button>
  <br>
  <br>
  <div class="result"></div>

  <script>
    let button = document.getElementsByTagName('button') [0]
    let divObj = document.getElementsByClassName('result') [0]
    button.addEventListener('click'.function(){
      // Create an object
      const xhr = new XMLHttpRequest()
      // Set the request method and URL
      xhr.open('GET'.'http://127.0.0.1:8282/index')
      // Send the request
      xhr.send()
      // Process the result returned by the server
      xhr.onreadystatechange = function() {
        /* readyState property value: 0 - the object is not initialized 1 - Open method executes 2 - send method executes 3 - Server returns partial results 4 - Server returns all results */
        if(xhr.readyState === 4) {
          // Check the response status code 2xx successfully
          if(xhr.status >= 200 && xhr.status < 300) {
            / / response
            // console.log(xhr.status)
            // console.log(xhr.statustext) // Status description
            // // response header
            // console.log(xhr.getAllResponseHeaders())
            // // response body
            // console.log(xhr.response)
            divObj.innerHTML = xhr.response
          }
        }
      }
    })
  </script>
</body>
</html>
Copy the code

Results:If you need to send a GET request with parameters, the URL should be written as:

xhr.open('GET'.'http://127.0.0.1:8282/index? a=100&b=200&c=300')
Copy the code
3.4 Sending a POST Request

Change xhr.open() from right GET to right POST:

xhr.open('POST'.'http://127.0.0.1:8282/index')
Copy the code

When the request body is sent using the POST method, the request body content is placed insendMethod, the format is not fixed, as long as the server can handle:

/ / form a
xhr.send('a=100&b=200&c=300')
/ / form 2
xhr.send('a:100&b:200&c:300')
// ...
Copy the code
3.5 Setting Request Header Information
// content-type Specifies the request body Type
// application/x-www-form-urlencoded query string type
xhr.setRequestHeader('Content-Type'.'application/x-www-form-urlencoded')
Copy the code

Custom request headers

xhr.setRequestHeader('Name'.'Alice')
Copy the code

In this case, the server must set the access-Control-allow-headers field, indicating that it can receive the processed request Headers. Otherwise, an error message is displayed:

app.post('/index'.(request, response) = > {
  response.setHeader('Access-Control-Allow-Origin'.The '*')
  response.setHeader('Access-Control-Allow-Headers'.The '*')
  response.send('post ajax')})Copy the code

The request header usually contains information that the server will validate.

3.6 When the Server Responds to JSON Data

If the server needs to return the DATA of the JSON object to the client, it needs to convert it into a JSON string and then send it. The following code is added to server.js:

// all() indicates methods that can match all requests
app.all('/json-data'.(request, response) = > {
  response.setHeader('Access-Control-Allow-Origin'.The '*')
  response.setHeader('Access-Control-Allow-Headers'.The '*')
  // To respond to json data, convert the JSON object to a string format
  const data = {
    'name': 'Alice'.'age': 34
  }
  response.send(JSON.stringify(data))
})
Copy the code

When the client processes the result, it needs to convert the JSON string into a JSON object:

button.addEventListener('click'.function() {
  let xhr = new XMLHttpRequest()
  xhr.open('GET'.'http://127.0.0.1:8282/json-data')
  xhr.send()
  xhr.onreadystatechange = function() {
    if(xhr.readyState === 4) {
      if(xhr.status >= 200 && xhr.status < 300) {
        // Convert the json data returned by the server to a JSON object
        let data = JSON.parse(xhr.response)
        console.log(data)
      }
    }
  }
})
Copy the code

Console:Or you can go directly toxhrObject to set the response body type tojson, there is no need to perform the conversion step:

button.addEventListener('click'.function() {
  let xhr = new XMLHttpRequest()
  xhr.responseType = 'json'
  xhr.open('GET'.'http://127.0.0.1:8282/json-data')
  xhr.send()
  xhr.onreadystatechange = function() {
    if(xhr.readyState === 4) {
      if(xhr.status >= 200 && xhr.status < 300) {
        let data = xhr.response
        console.log(data)
      }
    }
  }
})
Copy the code

Console:

3.7 Solving the Internet Explorer Cache Problem

In Internet Explorer, data sent after Ajax requests is cached, resulting in incorrect data in some time-sensitive scenarios. Therefore, you need to carry a timestamp parameter in the URL to make Internet Explorer think it is sending a different request each time:

 xhr.open('get'.'http://127.0.0.1:8282/json-data? t='+Date.now())
Copy the code
3.8 Handling Request Timeout and Network Exceptions

You can set a timeout on the XHR object, and if you don’t get a response within that time, it’s automatically canceled. For example, the result is returned after 3 seconds on the server:

// Delay response
app.get('/delay'.(request, response) = > {
  response.setHeader('Access-Control-Allow-Origin'.The '*')
  setTimeout(() = > {
    response.send('Delayed response')},3000)})Copy the code

The client set the timeout to 2s

<script>
  let button = document.getElementsByTagName('button') [0]
  let divObj = document.getElementsByTagName('div') [0]
  button.addEventListener('click'.function() {
    let xhr = new XMLHttpRequest()
    // Set timeout 2s to cancel the request
    xhr.timeout = 2000
    // Timeout callback
    xhr.ontimeout = function() {
      alert('Network is slow, please try again later! ')
    }
    xhr.open('GET'.'http://127.0.0.1:8282/delay')
    xhr.send()
    xhr.onreadystatechange = function() {
      if(xhr.readyState === 4) {
        if(xhr.status >= 200 && xhr.status < 300) {
          divObj.innerHTML = xhr.response
        }
      }
    }
  })
</script>
Copy the code

Console:You can also set the callback for network exceptions:

xhr.onerror = function() {
  alert('Network exception! ')}Copy the code

In the browser, set the network state tooffline, simulate the situation without network

3.9 Canceling a Request

Abort () on an XHR object can be used to cancel a request:

xhr.abort()
Copy the code
3.10 Repeated Sending Requests Problem

When we click the button multiple times to send a request, it will cause a certain amount of pressure on the server, and the operation of multiple requests is not necessary. To solve the problem of repeated requests, we need to cancel the last incomplete request when sending the request again.

<body>
  <button>Send the request</button>
  <script>
    let button = document.getElementsByTagName('button') [0]
    // Indicate whether an Ajax request is being processed
    let isSending = false  
    let xhr
    button.addEventListener('click'.function() {
      // If the last request still exists, cancel it and re-initiate the request
      if(isSending) {
        xhr.abort()
      }
      xhr = new XMLHttpRequest()
      isSending = true
      xhr.open('GET'.'http://127.0.0.1:8282/delay')
      xhr.send()
      xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
          // When the request is processed, the status code is false
          isSending = false}}})</script>
</body>
Copy the code