js中的原生網(wǎng)絡(luò)請求解讀
早在很多年前,我們發(fā)送網(wǎng)絡(luò)請求都是通過刷新或者跳轉(zhuǎn)頁面來獲取新的網(wǎng)絡(luò)數(shù)據(jù),從而達(dá)到渲染不同頁面的需求,用戶體驗是很差的,直到 ajax 橫空出生,才解決了這個問題,不需要刷新頁面便可以獲取請求數(shù)據(jù),這也是后來前后端分離的重要根源,大大的提高了網(wǎng)頁性能,優(yōu)化了用戶體驗。
而 ajax 的核心就是我們今天要學(xué)的的原生請求,**XMLHttpRequest**對象。
一. XMLHttpRequer 對象
創(chuàng)建: 通過 new 來創(chuàng)建。
1. 使用 XHR
open
: 接收三個參數(shù),分別為請求類型,請求的URL,請求是否異步,該方法為發(fā)送請求做好準(zhǔn)備send
: 接收一個參數(shù),請求體發(fā)送的內(nèi)容,如果不發(fā)送,必須寫入null,該方法開始發(fā)送請求status
: 相應(yīng)的 HTTP 狀態(tài)碼,當(dāng)位于 200~300 或者 等于 304 時,說明響應(yīng)成功返回。responseText
: 作為響應(yīng)體返回的文本statuesText
: 響應(yīng) HTTP 的狀態(tài)描述abort
: 該方法用來取消異步請求,會停止觸發(fā)事件,調(diào)用該方法后應(yīng)該取消對XHR對象的引用,不要重用XHR對象。onreadystatechange
: 用來監(jiān)聽請求位于哪個階段,該方法應(yīng)該在open前調(diào)用,該事件不會接收到event對象readyState
: 表示當(dāng)前請求位于哪個階段
0: 未初始化,尚未調(diào)用 open
1:已經(jīng)調(diào)用open,尚未調(diào)用 send
2:已經(jīng)送,已經(jīng)調(diào)用send,未收到響應(yīng)
3:接收中,已經(jīng)收到部分響應(yīng)
4:完成,接收到所有響應(yīng)
let xhr = new XMLHttpRequest(); // 創(chuàng)建XMLHttpRequest 實例 xhr.open("get", "http://127.0.0.1:3000/index", false); //設(shè)置為同步get請求 xhr.send(null); // 開始發(fā)送請求,并且阻塞后續(xù)代碼執(zhí)行,直到拿到響應(yīng) if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){ ?? ?console.log(xhr.responseText) // 檢驗狀態(tài)碼 }else{ ?? ?console.log('請求失敗') }
使用readyState:
每次該值的改變,都會觸發(fā)readystatechange 事件,因此我們可以在不同階段執(zhí)行不同操作
let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ // 監(jiān)聽請求完成 ?? ?if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){ ?? ??? ?console.log(xhr.responseText) ?? ?}else{ ?? ??? ?console.log('請求失敗') ?? ??? ?} ? ?? ?} } xhr.open("get", "http://127.0.0.1:3000/index", true); // 異步請求 xhr.send(null);
2. HTTP 頭部
① 默認(rèn)頭部信息
每個HTTP 請求和響應(yīng)都會攜帶頭部信息,我們來看一下默認(rèn)的一些請求頭部
Accept
: 瀏覽器可以處理的內(nèi)容類型Accept-Charset
:瀏覽器可以顯示的字符集Accept-Encoding
: 瀏覽器可以壓縮的編碼類型Connection
: 瀏覽器與服務(wù)的連接類型Cookie
:頁面中設(shè)置的CookieHost
: 發(fā)送請求頁面所在的域Referrer
:發(fā)送請求的頁面URLUser-Agent
: 瀏覽器的用戶代理字符串
②設(shè)置自定義頭部信息
setRequestHeader()
: 該方法接收兩個參數(shù),頭部字段的名稱和值,該方法必須在open之后,send 之前調(diào)用getResponseHeader()
: 從XHR對象獲取響應(yīng)頭部,只需要傳入獲取頭部的名稱即可getAllResponeHeaders()
: 獲取所有響應(yīng)頭信息
3. GET 請求
用于向服務(wù)器查詢某些信息,數(shù)據(jù)直接顯示在url中
① 傳參
需要將信息編碼后,添加到URL末尾,用 ? 隔開,各個參數(shù)用&隔開,參數(shù)的鍵值用=隔開
function addURLParam(url, name, value){ ?? ?const code = url.indexOf('?') == -1 ? '?' : '&'; ?? ?url += code; ?? ?url += (encodeURIComponent(name) + '=' + encodeURIComponent(value)) ?? ?return url; }
4. POST 請求
用于向服務(wù)器發(fā)送應(yīng)該保存的數(shù)據(jù),該數(shù)據(jù)在請求體中傳輸,只需要將要發(fā)送的數(shù)據(jù)寫入send方法中即可。
let btn = document.getElementById('btn') btn.onclick = function(){ ?? ?const xhr = new XMLHttpRequest(); ?? ?xhr.open('post', '/post', false); ?? ?xhr.send('sssss') }
5. XMLHttpRequest 標(biāo)準(zhǔn)2
① FormData 類型
用于將表單數(shù)據(jù)序列化,可以使用post請求模擬表單提交,使用該方法默認(rèn)將請求類型,設(shè)置為表單格式。
xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded")
實例反法:
append: 接收兩個參數(shù),通過鍵值對的方式,將數(shù)據(jù)填入表單
let form = new FormData(); form.append('age','12') form.append('name', '石頭山')
也可以在構(gòu)造函數(shù)中傳入一個表單。
let form = new FormData(document.forms[0);
② 超時
用于表示發(fā)送請求后需要等待多少毫秒,如果響應(yīng)不成功就中斷請求
timeout: 用來設(shè)置超時時間,如果超時則會觸發(fā) ontimeout 事件,同時 readyState 的狀態(tài)也會變成 4,同時調(diào)用 onreadystatechange 事件,并且超時之后訪問 statues 屬性會出錯
切記,同步請求不能設(shè)置超時
xhr.open('post', '/post', true); // 此處只能為 true? xhr.timeout = 1000; xhr.ontimeout = function(){ ?? ?console.log('請求超時') ?? ?} xhr.send(null)
二. 進(jìn)度事件
loadstart
: 在接收到響應(yīng)的第一個字節(jié)時觸發(fā)progress
: 在接收響應(yīng)期間反復(fù)觸發(fā)error
:在請求出錯時觸發(fā)abort
:在調(diào)用 abort()終止連接時觸發(fā)load
: 在成功接收完響應(yīng)時觸發(fā)loadend
:在通信完成時,在error,abort,load之后觸發(fā)
1. load事件
該屬性用來題代 readystatechange 事件,但是有一個問題,只有從服務(wù)器收到響應(yīng),無論狀態(tài)碼是什么,都會觸發(fā)該事件,因此還需要檢驗狀態(tài)碼來確保數(shù)據(jù)有效。
? ? ? ? ? ? const xhr = new XMLHttpRequest(); ? ? ? ? ? ? xhr.open('get', '/index', true); ? ? ? ? ? ? xhr.onload = function(){ ? ? ? ? ? ? ? ? if((xhr.status >= 200 && xhr.status<300) || xhr.status === 304){ ? ? ? ? ? ? ? ? ? ? console.log(xhr.responseText,'ss11'); ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? console.log('請求錯誤') ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? xhr.send(null)
2. progress 事件
在數(shù)據(jù)接收期間,該事件反復(fù)觸發(fā),該事件對象有三個屬性
lengthComputable
: 表示進(jìn)度信息是否可用position
:接收到的字節(jié)數(shù)totalSize
: 是響應(yīng)體頭部 Content-Length 的總字節(jié)數(shù)
? ? ? ? ? ? xhr.onprogress = function(event) { ? ? ? ? ? ? ? ? if(event.lengthComputable){ ? ? ? ? ? ? ? ? ? ? console.log(event.total, event.position) ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }
三. 跨資源共享
1. 跨域安全策略
默認(rèn)情況XHR只能訪問與發(fā)起請求的頁面在同一個域內(nèi)的資源。
- 原生跨域:給open傳入一個絕對路徑則跨源訪問
- 限制:
1.不能是使用setRequestHeader() 設(shè)置自定義頭部
2.不能發(fā)送和接收cookie
3.getAllResponseHeaders() 方法始終返回 空字符串
因此,在訪問本地資源時使用相對路徑,訪問遠(yuǎn)程資源時使用絕對路徑
2. 預(yù)檢請求
通過該機(jī)制,允許使用自定義頭部,除GET和POST外的方法,在發(fā)送請求時先發(fā)送一個預(yù)檢請求,這個請求使用OPTIONS方法發(fā)送以下頭部。
Origin
:與簡單請求相同Access-Control-Request-Method
: 請求希望使用的方法Access-Control-Request-Headers
: 自定義頭部列表
服務(wù)器可以確定是否允許這種類型的請求。會在響應(yīng)中發(fā)送如下頭部
Access-Control-Allow-Origin
: 允許的同源Access-Control-Allow-Methods
: 允許的方法Access-Control-Allow-Headers
: 允許的自定義頭部Access-Control-Allow-Max-Age
: 緩存預(yù)檢請求的秒數(shù)
預(yù)檢請求返回后,會緩存一段時間,在這段時間內(nèi)再次訪問不需要預(yù)檢。
3. 憑據(jù)請求
默認(rèn)情況下,跨源請求不提供憑據(jù),cookie,http認(rèn)證,SSl證書??梢酝ㄟ^將withCredentials 屬性設(shè)置為true來表明請求會發(fā)送憑證。
如果服務(wù)器允許攜帶,則在響應(yīng)頭部添加
Access-Control-Allow-Credentials: true.
四. 替代性跨源技術(shù)
1. 圖片探測
2. JSONP
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
javascript禁止訪客復(fù)制網(wǎng)頁內(nèi)容的實現(xiàn)代碼
這篇文章主要介紹了javascript禁止訪客復(fù)制網(wǎng)頁內(nèi)容的方法,具有一定參考借鑒價值,需要的朋友可以參考下2015-08-08使用JavaScript的ActiveXObject對象檢測應(yīng)用程序是否安裝的方法
這篇文章主要介紹了使用JavaScript的ActiveXObject對象檢測應(yīng)用程序是否安裝的方法,需要的朋友可以參考下2014-04-04微信小程序?qū)崿F(xiàn)slideUp、slideDown滑動效果及點(diǎn)擊空白隱藏功能示例
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)slideUp、slideDown滑動效果及點(diǎn)擊空白隱藏功能,涉及微信小程序事件響應(yīng)、頁面元素屬性動態(tài)操作實現(xiàn)滑動與蒙層功能相關(guān)技巧與注意事項,需要的朋友可以參考下2018-12-12微信小程序創(chuàng)建自定義全局函數(shù)以及其調(diào)用方法詳解
微信小程序有時需要函數(shù)里面調(diào)用函數(shù),下面這篇文章主要給大家介紹了關(guān)于微信小程序創(chuàng)建自定義全局函數(shù)以及其調(diào)用方法的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09javascript中數(shù)組的sort()方法的使用介紹
數(shù)組的sort()方法用于排序,在本文將為大家介紹下javascript中sort()方法的具體使用2013-12-12