硬核知識點——瀏覽器中的三類五種請求

對瀏覽器的請求進行劃分,能夠分爲三類:通常請求、Ajax請求、WebSocket請求,對於每種請求都有不一樣的產生方式,今天就以這個思想爲主線來一塊兒嘮一嘮。
css

1、通常請求

此處說的通常請求就是指瀏覽器會直接顯示響應體數據,這些請求會刷新\跳轉頁面。換個更加容易理解的說法吧,指的就是控制檯Network面板中除了XHR和WS部分顯示的請求。例如js、css、img資源。前端

2、Ajax請求

Ajax請求也是由瀏覽器發出,可是不會對界面進行任何操做,只是調用監視的回調函數並傳入響應相關數據,發出Ajax請求能夠經過三種方式:XHR、Fetch、Axios,其他的均不是Ajax請求。node

2.1 XHR

最先將Ajax推到歷史舞臺的關鍵技術就是XMLHttpRequest(XHR)對象,雖然目前已經有了一些過期的嫌疑,可是仍是頗有必要提一下它。下面就按照一個請求的整個生命週期來看一看該技術。ios

1、 對象的實例化git

既然要使用XHR,第一步就是要將該對象實例化github

const xhr = new XMLHttpRequest();

2、初始化操做web

將對象實例化後是否是緊接着就須要進行初始化操做,到底該請求要發給誰、經過什麼請求發、該請求究竟是同步發仍是異步發json

xhr.open(method, url, async)

3、請求頭設置axios

瞭解網絡的同窗本確定知道請求頭的概念,既然要與後端打交道,請求頭仍是有必要進行設置的(默認的配置不必定知足咱們高大上的需求),例如想發送json格式的內容,這個時候就須要設置Content-Type爲application/json後端

xhr.setRequestHeader('Content-Type', 'application/json');

4、接收請求的準備工做

瀏覽器除了設置常見的請求頭外,還須要指定響應數據類型,獲得響應後自動解析。目前支持的類型有string、arraybuffer、blob、document、json、text、ms-stream。

xhr.responseType('json')

5、發送請求

前期工做都準備好了,接下來就是激動人心的時刻了,看好呀,要按開始鍵發送請求啦。

xhr.send(data)

6、監聽響應

我喊一聲美女,人家確定要回應一下呀,畢竟顏值在這,不迴應該是多麼不給面子的一件事呀!!!爲了等待人家的迴應,則須要分三步進行:

  1. 進入監聽狀態,放在這就是經過onreadystatechange進行監聽。

  2. 等待正面迴應。readyStatus表徵目前的狀態,當readyStatus爲4(請求完成),響應算是接收到了

  3. 處理響應。不能一股腦的處理所有響應吧,畢竟也是要面子的人,我確定只但願接收我喜歡的信息吧,就喜歡狀態碼在200~299之間的,別的一律pass掉。

xhr.onreadystatechange = () => {
if (xhr.readyState == 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response);
}
}
}

7、中斷請求

正常流程算是走完了,確定還有非正常流程,發起請求後我後悔了,不想獲得對方的迴應了,此時仍然有辦法——中斷請求

xhr.abort()

注:本文不是文檔學習,詳細使用請見https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

2.2 Fetch

長江後浪推前浪,互聯網技術發展這麼快,出現了新的技術(Fetch)可以執行XMLHttpRequest對象的全部任務,該技術使用更容易,接口更現代化,可以在Web工做線程等現代Web工具中使用。(Fetch必須是異步,XMLHttpRequest可同步可異步)。

const payload = JSON.stringify({
test: 'test'
});

let headersObj = new Headers({
'Content-Type':'application/json'
});

let request = new Request('http://localhost:8080');

fetch(request, {
method: 'POST',
body: payload,
headers: headersObj
})
.then((response) => response.json())
.then(console.log)

上述代碼雖然簡單,可是已經囊括了Fetch API中全部的概念:fetch、Headers、Request、Response、Body混入。

  1. fetch()

fetch()方法暴露在全局做用域中,包括主頁面執行線程、模塊和工做線程,調用該方法,瀏覽器就會向給定URL發送請求。
(1)fetch(input[, init]):接收兩個參數,input爲要獲取的資源,__init爲一個配置對象,配置須要傳入的參數,知足更多複雜的需求
(2)返回一個promise對象,從而鏈式的進行處理

  1. Headers

至關於 response/request 的頭信息,可使你查詢到這些頭信息,或者針對不一樣的結果作不一樣的操做。該對象包含檢索、設置、添加、刪除,設置完本身須要的頭信息後就能夠將其掛載到fetch中的配置信息中。

  1. Request

該對象是獲取資源請求的接口,暴露了請求和相關信息。能夠將該對象的實例做爲fetch函數中的第一個參數

  1. Response

該對象是獲取資源響應的接口,並暴露了響應的相關信息。

  1. Body混入

提供了與 response/request 中的 body 有關的方法,能夠定義它的內容形式以及處理方式。在Body混入中提供了5個方法,用於將ReadableStream轉存到緩衝區的內存中,將緩衝區轉換爲某種JavaScript對象類型,以及經過Promise產生結果。

(1)Body.text():返回Promise,解決將緩衝區轉存獲得的UTF-8格式字符串

(2)Body.json():返回Promise,解決將緩衝區轉存獲得的JSON

(3)Body.formData():返回Promise,解決將緩衝區轉存獲得的FormData實例

(4)Body.arrayBuffer():返回Promise,解決將緩衝區轉存獲得的ArrayBuffer

(5)Body.text():返回Promise,解決將緩衝區轉存獲得的Blob實例

2.3 Axios

Axios應該是目前前端最流行的Ajax請求庫,具備如下特色:

  1. 基於Promise的異步Ajax請求庫

  2. 瀏覽器端/node端均可以使用

  3. 支持請求/響應攔截器

  4. 支持請求取消

  5. 請求/響應數據轉換

  6. 批量發送請求

對於Axios仍是比較有意思的,本次只說一下其簡單使用,下一期準備剖析一下其源碼,有興趣的小夥伴能夠先搬好小板凳佔個坑,關注一下。

// 默認配置
axios.defaults.baseURL = 'http://localhost:8080'

// 請求攔截器
axios.interceptors.request.use(
config => {
console.log('request interceptor resolved');
return config;
},
error => {
console.log('request interceptor rejected');
return Promise.reject(error);
}
);

// 響應攔截器
axios.interceptors.response.use(
response => {
console.log('response interceptor resolved');
return response;
},
error => {
console.log('response interceptor rejected');
return Promise.reject(error);
}
);

let cancel; // 用於保存取消請求的函數
axios('/', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
data: {
test: 'test'
},
// 取消請求
cancelToken: new axios.CancelToken((c) => {
cancel = c;
})
})
.then((response) => {
console.log(response.data)
})

// 若想取消請求,直接調用下面函數
// cancel();

上述代碼已經囊括了Axios庫中大多數核心內容,包括axios()函數、默認設置、請求/響應攔截器、取消請求(內部設計的很巧妙,想知道的請看下期講解)

  1. axios()

完成相應配置併發送請求,調用方式有多種語法糖,同窗們能夠按需使用。

  1. 默認設置

經過axios.defaults.xxx能夠完成不少全局配置,提升代碼的複用。(提升複用真是完美的編碼思想)

  1. 請求/響應攔截器

請求攔截器的做用就是在請求發送以前先進行一些列的處理;響應攔截器的做用就是觸發請求的回調以前執行響應攔截器,對響應作一些預處理操做

  1. 取消請求

經過配置cancelToken對象並緩存用於取消請求的cancel函數,在須要的時候觸發該函數取消請求(內部其實就是調用的xhr.abort())

對於更多使用見詳細使用文檔https://github.com/axios/axios

3、WebSocket請求

下面來聊聊這個傳奇協議——WebSocket,WebSockt經過一個長時鏈接實現與服務器全雙工、雙向的通訊。(特別提醒:同源策略不適用於WebSocket)

let ws = new WebSocket('ws://127.0.0.1:8080');

// 在鏈接創建成功時
ws.onopen = () => {
ws.send('websocket')
}

// 在接收到消息時
ws.onmessage = (event) => {
console.log(event.data);
}

// 在發生錯誤時
ws.onerror = () => {
console.log('error');
}

// 在鏈接關閉時
ws.onclose = () => {
console.log('close');
}

上述代碼已經囊括大部分WebSocket的概念,實例化WebSocket創建與服務端的鏈接;經過事件監聽便可瞭解WebSokcet鏈接目前的狀態;經過send()函數便可向服務端發送內容;當服務端發送消息時便可觸發message事件,經過event.data屬性獲取其有效載荷。

本篇文章雖然比較簡單,可是能夠幫助咱們認清楚請求實際上是分爲三類的,這是我最最最大的收穫,歡迎小夥伴們可以給出本身的想法。

1.若是以爲這篇文章還不錯,來個分享、點贊、在看三連吧,讓更多的人也看到~

2.關注公衆號前端巔峯,領取學習資料,按期爲你推送原創深度好文


本文分享自微信公衆號 - 前端巔峯(Java-Script-)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索