對瀏覽器的請求進行劃分,能夠分爲三類:通常請求、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、監聽響應
我喊一聲美女,人家確定要回應一下呀,畢竟顏值在這,不迴應該是多麼不給面子的一件事呀!!!爲了等待人家的迴應,則須要分三步進行:
進入監聽狀態,放在這就是經過onreadystatechange進行監聽。
等待正面迴應。readyStatus表徵目前的狀態,當readyStatus爲4(請求完成),響應算是接收到了
處理響應。不能一股腦的處理所有響應吧,畢竟也是要面子的人,我確定只但願接收我喜歡的信息吧,就喜歡狀態碼在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混入。
fetch()
fetch()方法暴露在全局做用域中,包括主頁面執行線程、模塊和工做線程,調用該方法,瀏覽器就會向給定URL發送請求。
(1)fetch(input[, init]):接收兩個參數,input爲要獲取的資源,__init爲一個配置對象,配置須要傳入的參數,知足更多複雜的需求
(2)返回一個promise對象,從而鏈式的進行處理
Headers
至關於 response/request 的頭信息,可使你查詢到這些頭信息,或者針對不一樣的結果作不一樣的操做。該對象包含檢索、設置、添加、刪除,設置完本身須要的頭信息後就能夠將其掛載到fetch中的配置信息中。
Request
該對象是獲取資源請求的接口,暴露了請求和相關信息。能夠將該對象的實例做爲fetch函數中的第一個參數
Response
該對象是獲取資源響應的接口,並暴露了響應的相關信息。
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請求庫,具備如下特色:
基於Promise的異步Ajax請求庫
瀏覽器端/node端均可以使用
支持請求/響應攔截器
支持請求取消
請求/響應數據轉換
批量發送請求
對於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()函數、默認設置、請求/響應攔截器、取消請求(內部設計的很巧妙,想知道的請看下期講解)
axios()
完成相應配置併發送請求,調用方式有多種語法糖,同窗們能夠按需使用。
默認設置
經過axios.defaults.xxx能夠完成不少全局配置,提升代碼的複用。(提升複用真是完美的編碼思想)
請求/響應攔截器
請求攔截器的做用就是在請求發送以前先進行一些列的處理;響應攔截器的做用就是觸發請求的回調以前執行響應攔截器,對響應作一些預處理操做
取消請求
經過配置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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。