axios從無從下手到手到擒來(1)-使用XMLHttpRequest封裝簡單的ajax請求函數

1. XHR的MDN文檔

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest前端


2. XHR的理解
1). 使用XHR對象能夠發送ajax請求與服務端進行交互
2). 前端能夠獲取數據,而無需讓整個頁面進行刷新
3). 只更新Web頁面的局部,而不影響用戶的操做

3. 通常http請求與ajax請求的區別
1). ajax請求是一種特別的http請求
2). 對服務器端來講沒有任何區別,區別在瀏覽器端
3). 對瀏覽器端來講,只有XHR或fetch發出的請求才是ajax請求,其餘的都是通常http請求
4). 瀏覽器端接收到響應:
    a. 通常請求: 瀏覽器會直接顯示響應數據體,也就是刷新/跳轉頁面
    b. ajax請求: 瀏覽器不會對頁面作任何更新操做,只是調用相應的回調函數並傳入響應數據

4. XHR的API
1). XMLHttpRequest() 建立XHR對象的構造函數
2). status 響應狀態碼,好比404,200...
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(url,method[,async]) 初始化一個請求
12). send(data) 發送請求
13). abort() 中斷請求
14). getResponseHeader(name)  獲取指定的響應頭
15). getAllResponseHeaders() 獲取全部的響應頭組成的字符串
16). setRequestHeader(name,value) 設置請求頭

5. 使用XHR簡單封裝axios
  封裝目的
    a. 函數的返回值類型爲Promise,成功的結果爲response,失敗的結果爲error
    b. 可以處理GET/POST/DELETE/PUT等類型的請求
    c. 構造函數的參數爲一個配置對象
    d. 響應的json數據自動解析爲js對象
(function (window) {
  //參數爲配置對象,默認get請求,queryParams和data都爲空對象
  function axios({url, method = 'GET', params = {}, data = {}}) {
    //返回一個Promise
    return new Promise((resolve, reject) => {
      //處理method的大小寫
      method = method.toUpperCase()

      //處理params, 拼接成queryString
      if (params) {
        let queryString = ''
        Object.keys(params).forEach(key => {
          queryString += `${key}=${params[key]}&`
        })
        //去掉最後一個&
        queryString = queryString.substring(0, queryString.length - 1)
        //把queryString拼到url上
        url += '?' + queryString
      }

      //建立xhr對象
      const request = new XMLHttpRequest()
      //打開鏈接(尚未請求)
      request.open(method, url)
      //發送請求
      if (method === 'GET' || method === 'DELETE') {
        request.send()
      } else if (method === 'POST' || method === 'PUT') {
        //設置請求頭類型
        request.setRequestHeader('ContentType', 'application/json;charset=utf-8')
        //將data從js對象轉成json string
        request.send(JSON.stringify(data))
      }

      //綁定狀態改變監聽
      request.onreadystatechange = () => {
        //請求沒有完成
        if (request.readyState !== 4) return
        //只有status在[200,300)之間才表明成功
        const {status, statusText} = request
        //axios的源碼中也是這樣的簡單粗暴
        if (status >= 200 & status < 300) {
          //response對象
          const response = {
            data: JSON.parse(request.response),
            status,
            statusText
          }
          //resolve promise
          resolve(response)
        } else {
          //其餘狀態都表示失敗, reject promise, 給予一個友好的提示
          reject(new Error('request failed! response code = ' + status))
        }
      }
    })
  }

  window.axios = axios
})(window)
相關文章
相關標籤/搜索