1. 程式人生 > 實用技巧 >axios入門(二)

axios入門(二)

XHR理解和使用

  1. 使用XMLHttpRequest(XHR)物件可以與伺服器互動,也就是傳送ajax請求
  2. 前端可以獲取到資料,而無需讓整個的頁面重新整理。
  3. 這使得Web可以只更新頁面的區域性,而不影響使用者的操作

區別一般http請求與ajax請求

  1. ajax請求是一種特別的http請求
  2. 對伺服器來說,沒有任何區別,區別在瀏覽器端
  3. 瀏覽器端傳送請求:只有XHR或fetch發出的才是ajax請求,其他的都是非ajax請求
  4. 瀏覽器端接收到響應
    • 一般請求:瀏覽器一般會直接顯示響應體資料,也就是我們常說的重新整理/跳轉頁面
    • ajax請求:瀏覽器不會對介面進行任何更新操作,只是呼叫監視的回撥函式並傳入響應相關資料

API

  1. XMLHttpRequest():建立XHR物件的建構函式
  2. status:響應狀態碼值,比如2000,404
  3. statusText: 響應狀態文字
  4. readyState:標識請求狀態的只讀屬性
    0: 初始
    1: open()之後
    2: send()之後
    3: 請求中
    4: 請求完成
  5. onreadystatechange:繫結readyState給變的監聽
  6. responseType:指定響應資料型別,如果是‘json’,得到響應後自動解析響應體資料
  7. response: 響應體資料,型別取決於responseType的指定
  8. timeout: 指定請求超時時間, 預設為0 代表沒有限制
  9. ontimeout: 繫結超時的監聽
  10. onerror: 繫結請求網路錯誤的監聽
  11. open(): 初始化一個請求, 引數為: (method, url[, async])
  12. send(data): 傳送請求
  13. abort(): 中斷請求
  14. getResponseHeader(name): 獲取指定名稱的響應頭值
  15. getAllResponseHeaders(): 獲取所有響應頭組成的字串
  16. setRequestHeader(name, value): 設定請求頭

XHR的ajax封裝(簡單版axios)

特點

  1. 函式的返回值為promise,成功的結果為response,異常的結果為error
  2. 能處理多種型別的請求:GET/POST/PUT/DELETE
  3. 函式的引數為一個配置物件
{
url: '', // 請求地址
method: '', // 請求方式GET/POST/PUT/DELETE
params: {}, // GET/DELETE 請求的query 引數
data: {}, // POST 或DELETE 請求的請求體引數
}
  1. 響應json資料自動解析為js

編碼實現

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>使用XHR封裝ajax請求引數</title>
</head>
<body>
  <button onclick="testGet()">傳送GET請求</button><br>
  <button onclick="testPost()">傳送POST請求</button><br>
  <button onclick="testPut()">傳送PUT請求</button><br>
  <button onclick="testDelete()">傳送Delete請求</button><br>


  <script>

    /* 1. GET請求: 從伺服器端獲取資料*/
    function testGet() {
      axios({
        // url: 'http://localhost:3000/posts',
        url: 'http://localhost:3000/posts2',
        method: 'GET',
        params: {
          id: 1,
          xxx: 'abc'
        }
      }).then(
        response => {
          console.log(response)
        },
        error => {
          alert(error.message)
        }
      )
    }

    /* 2. POST請求: 伺服器端儲存資料*/
    function testPost() {
      axios({
        url: 'http://localhost:3000/posts',
        method: 'POST',
        data: {
          "title": "json-server---", 
          "author": "typicode---"
        }
      }).then(
        response => {
          console.log(response)
        },
        error => {
          alert(error.message)
        }
      )
    }

    /* 3. PUT請求: 伺服器端更新資料*/
    function testPut() {
      axios({
        url: 'http://localhost:3000/posts/1',
        method: 'put',
        data: {
          "title": "json-server+++", 
          "author": "typicode+++"
        }
      }).then(
        response => {
          console.log(response)
        },
        error => {
          alert(error.message)
        }
      )
    }

    /* 2. DELETE請求: 伺服器端刪除資料*/
    function testDelete() {
      axios({
        url: 'http://localhost:3000/posts/2',
        method: 'delete'
      }).then(
        response => {
          console.log(response)
        },
        error => {
          alert(error.message)
        }
      )
    }

    /* 
    1.函式的返回值為promise, 成功的結果為response, 失敗的結果為error
    2.能處理多種型別的請求: GET/POST/PUT/DELETE
    3.函式的引數為一個配置物件
      {
        url: '',   // 請求地址
        method: '',   // 請求方式GET/POST/PUT/DELETE
        params: {},  // GET/DELETE請求的query引數
        data: {}, // POST或DELETE請求的請求體引數 
      }
    4.響應json資料自動解析為js的物件/陣列
    */
    function axios({
      url,
      method='GET',
      params={},
      data={}
    }) {
      // 返回一個promise物件
      return new Promise((resolve, reject) => {

        // 處理method(轉大寫)
        method = method.toUpperCase()

        // 處理query引數(拼接到url上)   id=1&xxx=abc
        /* 
        {
          id: 1,
          xxx: 'abc'
        }
        */
        let queryString = ''
        Object.keys(params).forEach(key => {
          queryString += `${key}=${params[key]}&`
        })
        if (queryString) { // id=1&xxx=abc&
          // 去除最後的&
          queryString = queryString.substring(0, queryString.length-1)
          // 接到url
          url += '?' + queryString
        }


        // 1. 執行非同步ajax請求
        // 建立xhr物件
        const request = new XMLHttpRequest()
        // 開啟連線(初始化請求, 沒有請求)
        request.open(method, url, true)

        // 傳送請求
        if (method==='GET' || method==='DELETE') {
          request.send()
        } else if (method==='POST' || method==='PUT'){
          request.setRequestHeader('Content-Type', 'application/json;charset=utf-8') // 告訴伺服器請求體的格式是json
          request.send(JSON.stringify(data)) // 傳送json格式請求體引數
        }

        // 繫結狀態改變的監聽
        request.onreadystatechange = function () {
          // 如果請求沒有完成, 直接結束
          if (request.readyState!==4) {
            return
          }
          // 如果響應狀態碼在[200, 300)之間代表成功, 否則失敗
          const {status, statusText} = request
          // 2.1. 如果請求成功了, 呼叫resolve()
          if (status>=200 && status<=299) {
            // 準備結果資料物件response
            const response = {
              data: JSON.parse(request.response),
              status,
              statusText
            }
            resolve(response)
          } else { // 2.2. 如果請求失敗了, 呼叫reject()
            reject(new Error('request error status is ' + status))
          }
        }
      })
    }



  </script>
</body>
</html>