XMLHttpRequest 對象發送請求的步驟

關於原生 XMLHttpRequest 發送請求可以做的一些事情。

目前 XMLHttpRequest 實列是被所有瀏覽器支持的。

首先創建一個 XHR 對象實例。

const request = new XMLHttpRequest()

之後可以配置一些 返回值類型、超時時間、跨域請求攜帶COOKIE之類的。

 request.responseType = responseType
 request.timeout = timeOut
 request.withCredentials = withCredentials

調用 XHR 對象的 open() 方法, 傳入請求類型‘GET'/'POST' 之類的, 請求地址、 async 的值爲 boolean 類型的。

request.open(method, url, true)

之後可以爲 XHR 對象 添加時間處理器  onreadystatechange , 可以針對請求的一些狀態來做一些處理。

 request.onreadystatechange = function handleLoad() {
      if (request.readyState !== 4) {
        return
      }
      if (request.status === 0) {
        return
      }
      // 更多的一些騷操作
    }

還有一些 錯誤處理、超時處理之類的

 // 錯誤處理
    request.onerror = function handleError() {
      reject(createError('Network Error', config, null, request))
    }

    // 超時處理
    request.ontimeout = function handleTimeout() {
      reject(createError(`Timeout of ${timeOut} ms exceeded`, config, 'ECONNABORTED', request))
    }

然後會做一點簡單的 xsrf 防禦之類的,關於xsrf 防禦,通常是服務端在客戶端種下一個 cookie ,cookie 的值是後端出的,然後客戶端在發請求的時候, 在請求頭裏面添加上與後端協定好的字段,把 cookie 的值填充進去,這樣後端收到請求的時候會看看請求頭裏面有沒有協定好的字段,然後值是不是對的上,就可以防禦到跨站攻擊拉。

// 這裏先讀到 cookie 然後把 cookie 添加到 headers 的配置裏面,後面配置頭部的時候會一起加進去 
if ((withCredentials || isURLSameOrigin(url!)) && xsrfCookieName) {
      const xsrfValue = cookie.read(xsrfCookieName)
      if (xsrfValue && xsrfHeaderName) {
        headers[xsrfHeaderName] = xsrfValue
      }
    }

配置頭部, 因爲之前有一個存放 Header 配置的  headers 對象,所以在 xsrf 防禦的時候會先把配置的 header 名字和值加到 headers 對象裏面,現在直接循環出來統一配置就好拉。

   Object.keys(headers).forEach(name => {
      // 判斷一下 如果 data = null 就沒必要配置 headers 的 content-type 了
      if (data === null && name.toLowerCase() === 'content-type') {
        delete headers[name]
      } else {
        request.setRequestHeader(name, headers[name])
      }
    })

最後發送這個請求

request.send(data)

 

這個請求自己封裝了一下,返回一個 Promise 對象,所以會出現 reject 方法, resolve 的調用在 onreadystatechange 裏面做處理,請求狀態成功了之後會去調 resolve 的,示例代碼裏面只是沒貼出來,這裏只是記錄一下 XHR 對象發送請求大概要做的步驟。

 

那之後可以根據 Promise 鏈式調用的特性去做請求攔截和響應攔截,在加上取消請求的方法,還有上傳下載的監控之類的,最後能夠得到一個 小Axios........

其實上面的代碼也是參考了 Axios 做的一個封裝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章