AJAX —- 3 XMLHttpRequest ◆ Promise

XMLHttpRequest

Definition: XMLHttpRequest object is used for server interaction. Through XMLHttpRequest, you can request a specific URL and obtain data without refreshing the page.

Relationship: Axios internally uses XMLHttpRequest to interact with the server

step:

1. Create XMLHttpRequest object

2. Configure the request method and request url address

3. Listen to the loadend event and receive the response result

4. Initiate a request

 <p></p>
  <script>
    /**
     * Goal: Use the XMLHttpRequest object to communicate with the server
     * 1. Create XMLHttpRequest object
     * 2. Configure the request method and request url address
     * 3. Listen to the loadend event and receive the response result
     * 4. Initiate a request
    */
  // 1. Create XMLHttpRequest object
  const xhr = new XMLHttpRequest()

  // 2. Configure the request method and request url address
  xhr.open('GET', 'http://hmajax.itheima.net/api/province')

  // 3. Listen to the loadend event and receive the response result
  xhr.addEventListener('loadend', () => {
    console.log(xhr.response)
    const data = JSON.parse(xhr.response).list.join('<br>')
    // console.log(data.list.join('<br>'))
    document.querySelector('p').innerHTML = data
  })

  // 4. Initiate a request
  xhr.send()
  </script>

XMLHttpRequest-query parameters

<body>
  <p class="city-p"></p>
  <script>
    /**
     * Goal: Use XHR to carry query parameters to display a list of cities under a certain province
    */
   const xhr = new XMLHttpRequest()
   xhr.open('GET', 'http://hmajax.itheima.net/api/city?pname=Sichuan Province')
   xhr.addEventListener('loadend', () => {
    console.log(xhr.response)
    const data = JSON.parse(xhr.response)
    document.querySelector('.city-p').innerHTML = data.list.join('<br>')
   })
   xhr.send()
  </script>
</body>

Query parameter object -> query parameter string

new URLSearchParams()

Convert to URLSearchParams object, convert to string in toString()

// 3. Organize query parameter strings
    const qObj = {
      Attribute name: attribute value
    }

    // Query parameter object->query parameter string
    const paramsObj = new URLSearchParams(qObj)
    const queryString = paramsObj.toString()
    console.log(queryString)

Case_Region Query

<body>
  <div class="container">
    <form id="editForm" class="row">
      <!-- Enter the province name -->
      <div class="mb-3 col">
        <label class="form-label">province name</label>
        <input type="text" value="Beijing" name="province" class="form-control province" placeholder="Please enter the name of the province" />
      </div>
      <!-- Enter the city name -->
      <div class="mb-3 col">
        <label class="form-label">city name</label>
        <input type="text" value="Beijing" name="city" class="form-control city" placeholder="Please enter the city name" />
      </div>
    </form>
    <button type="button" class="btn btn-primary sel-btn">Query</button>
    <br><br>
    <p>Region list:</p>
    <ul class="list-group">
      <!-- Example region -->
      <li class="list-group-item">Dongcheng District</li>
    </ul>
  </div>
  <script src="//i2.wp.com/cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    /**
     * Goal: According to the name of the province and city, query the corresponding region list
    */
  // 1. Query button -> click event
  document.querySelector('.sel-btn').addEventListener('click', () => {
    // 2. Collect province and city names
    const pname = document.querySelector('.province').value
    const cname = document.querySelector('.city').value

    // 3. Organize the query parameter string
    const qObj = {
      pname,
      cname
    }

    // query parameter object -> query parameter string
    const paramsObj = new URLSearchParams(qObj)
    const queryString = paramsObj.toString()
    console.log(queryString)

    // 4. Use the XHR object to query the region list
    const xhr = new XMLHttpRequest()
    xhr.open('GET', `http://hmajax.itheima.net/api/area?${queryString}`)
    xhr. addEventListener('loadend', () => {
      console. log(xhr. response)
      const data = JSON. parse(xhr. response)
      const htmlStr = data.list.map(areaName => {
        return `<li class="list-group-item">${areaName}</li>`
      }).join('')
      console.log(htmlStr)
      document.querySelector('.list-group').innerHTML = htmlStr
    })
    xhr.send()
  })
  </script>
</body>

Promise

Promise objects are used to represent the final completion (or failure) of an asynchronous operation and its result value.

grammar:

<script>
    /**
     * Goal: Use Promise to manage asynchronous tasks
    */
  //Create Promise object
   const p = new Promise((resolve, reject) => {
    //When the Promise object is created, the code here will be executed
    // 2. Execute asynchronous tasks
    setTimeout(() => {
      // resolve() => 'fulfilled status-fulfilled' => then()
      resolve('Simulate AJAX request -- success')
      // reject() => 'rejected status-rejected' => then()
      // reject(new Error('Simulate AJAX request -- failure'))
    }, 2000)
   })
   console.log(p) // pending pending
  
  // 3. Get the results
  p.then(result => {
    console.log(result)
  }).catch(error => {
    console.log(error)
  })
  </script>

Promise – three states

Role: Understand how Promise objects are associated with processing functions, and the order of code execution

Concept: A Promise object must be in one of the following states:

Pending: Initial status, neither honored nor rejected

Fulfilled: means that the operation was completed successfully

Rejected: means that the operation failed

Note: Once the Promise object is honored/rejected, it is finalized and the status cannot be changed.

Package simple version axios

Encapsulation_simple axios_get province list

<body>
  <p class="my-p"></p>
  <script>
    /**
     * Goal: Encapsulation_Simple axios function_Get the list of provinces
     * 1. Define the myAxios function, receive the configuration object, and return the Promise object
     * 2. Initiate an XHR request, the default request method is GET
     * 3. Call success/failure handler
     * 4. Use the myAxios function to obtain the province list display
    */
  // 1. Define the myAxios function, receive the configuration object, and return the Promise object
  function myAxios(config) {
    return new Promise((resolve, reject) => {
      // 2. Initiate an XHR request, the default request method is GET
      const xhr = new XMLHttpRequest()
      xhr.open(config.method || 'GET', config.url)
      xhr.addEventListener('loadend', () => {
        // 3. Call success/failure handlers
        if(xhr.status >= 200 & amp; & amp; xhr.status < 300) {
          resolve(JSON.parse(xhr.response))
        }else {
          reject(new Error(xhr.response))
        }
      })
      xhr.send()
    })
  }
  
      // 4. Use the myAxios function to get the list of provinces to display
      myAxios({
        url: 'http://hmajax.itheima.net/api/province'
      }).then(result => {
        console.log(result)
        document.querySelector('.my-p').innerHTML = result.list.join('<br>')
      }).catch(error => {
        console.dir(error)
        document.querySelector('.my-p').innerHTML = error.message
      })
  </script>
</body>

Package_Simple axios_Get the list of provinces

<body>
  <p class="my-p"></p>
  <script>
    /**
     * Goal: Encapsulation_simple axios function_get region list
     * 1. Determine if there is params option and carry query parameters
     * 2. Use URLSearchParams to convert and carry to the url
     * 3. Use the myAxios function to get the region list
    */
    function myAxios(config) {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        // 1. Determine if there is params option and carry query parameters
        if(config. params) {
          // 2. Use URLSearchParams to convert and carry to the url
          const paramsObj = new URLSearchParams(config.params)
          const queryString = paramsObj.toString()
          // Splice the query parameter string after url?
          config.url + = `?${queryString}`
        }
        xhr.open(config.method || 'GET', config.url)
        xhr.addEventListener('loadend', () => {
          if (xhr.status >= 200 & amp; & amp; xhr.status < 300) {
            resolve(JSON.parse(xhr.response))
          } else {
            reject(new Error(xhr.response))
          }
        })
        xhr. send()
      })
    }

    // 3. Use the myAxios function to get the region list
    myAxios({
      url: 'http://hmajax.itheima.net/api/area',
      params: {
        pname: 'Sichuan Province',
        cname: 'Chengdu'
      }
    }).then(result => {
        console.log(result)
        document.querySelector('.my-p').innerHTML = result.list.join('<br>')
      }).catch(error => {
        console.dir(error)
        document.querySelector('.my-p').innerHTML = error.message
      })
  </script>
</body>

Package_simple axios_registered user

<body>
  <button class="reg-btn">registered user</button>
  <script>
    /**
     * Goal: Encapsulation_simple axios function_registered user
     * 1. Judging that there is a data option, carrying the request body
     * 2. Convert the data type and send it in send
     * 3. Use the myAxios function to complete the user registration
    */
    function myAxios(config) {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()

        if (config.params) {
          const paramsObj = new URLSearchParams(config.params)
          const queryString = paramsObj.toString()
          config.url += `?${queryString}`
        }
        xhr.open(config.method || 'GET', config.url)

        xhr. addEventListener('loadend', () => {
          if (xhr.status >= 200 & amp; & amp; xhr.status < 300) {
            resolve(JSON. parse(xhr. response))
          } else {
            reject(new Error(xhr.response))
          }
        })

        // 1. Judging that there is a data option, carry the request body
        if(config.data) {
          // Convert data type and send in send
          const jsonStr = JSON.stringify(config.data)
          xhr.setRequestHeader('Content-Type', 'application/json')
          xhr.send(jsonStr)
        }else {
          // If there is no data parameter, initiate the request normally
          xhr.send()
        }
      })
    }
    
    // Bind the click event to the registration button
    document.querySelector('.reg-btn').addEventListener('click', () => {
      // 3. Use the myAxios function to complete the user registration
      myAxios({
        url: 'http://hmajax.itheima.net/api/register',
        method: 'POST',
        data: {
          username: 'itheima555',
          password: '1234567'
        }
      }).then(result => {
        console.log(result)
      }).catch(error => {
        console.dir(error)
      })
    })
 </script>
</body>

Case – Weather Forecast