全面分析前端的網絡請求方式


一、前端進行網絡請求的關注點

大多數情況下,在前端發起一個網絡請求我們只需關注下面幾點:

  • 傳入基本參數(url,請求方式)
  • 請求參數、請求參數類型
  • 設置請求頭
  • 獲取響應的方式
  • 獲取響應頭、響應狀態、響應結果
  • 異常處理
  • 攜帶cookie設置
  • 跨域請求

 

二、前端進行網絡請求的方式

  • form表單、ifream、刷新頁面
  • Ajax - 異步網絡請求的開山鼻祖
  • jQuery - 一個時代
  • fetch - Ajax的替代者
  • axios、request等眾多開源庫

 

三、關於網絡請求的疑問

  • Ajax的出現解決了什么問題
  • 原生Ajax如何使用
  • jQuery的網絡請求方式
  • fetch的用法以及坑點
  • 如何正確的使用fetch
  • 如何選擇合適的跨域方式

帶着以上這些問題、關注點我們對幾種網絡請求進行一次全面的分析。

 

四、Ajax的出現解決了什么問題

在Ajax出現之前,web程序是這樣工作的:

這種交互的的缺陷是顯而易見的,任何和服務器的交互都需要刷新頁面,用戶體驗非常差,Ajax的出現解決了這個問題。Ajax全稱Asynchronous JavaScript + XML(異步JavaScript和XML)

使用Ajax,網頁應用能夠快速地將增量更新呈現在用戶界面上,而不需要重載(刷新)整個頁面。

Ajax本身不是一種新技術,而是用來描述一種使用現有技術集合實現的一個技術方案,瀏覽器的XMLHttpRequest是實現Ajax最重要的對象(IE6以下使用ActiveXObject)。

盡管X在Ajax中代表XML, 但由於jsON的許多優勢,比如更加輕量以及作為Javascript的一部分,目前jsON的使用比XML更加普遍。

廣州vi設計http://www.maiqicn.com 辦公資源網站大全 https://www.wode007.com

五、原生Ajax的用法

這里主要分析XMLHttpRequest對象,下面是它的一段基礎使用:

        var xhr = new XMLHttpRequest(); xhr.open('post','www.xxx.com',true) // 接收返回值 xhr.onreadystatechange = function(){ if(xhr.readyState === 4 ){ if(xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ console.log(xhr.responseText); } } } // 處理請求參數 postData = {"name1":"value1","name2":"value2"}; postData = (function(value){ var dataString = ""; for(var key in value){ dataString += key+"="+value[key]+"&"; }; return dataString; }(postData)); // 設置請求頭 xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // 異常處理 xhr.onerror = function() { console.log('Network request failed') } // 跨域攜帶cookie xhr.withCredentials = true; // 發出請求 xhr.send(postData);

下面分別對XMLHttpRequest對象常用的的函數、屬性、事件進行分析。

函數

open

用於初始化一個請求,用法:

xhr.open(method, url, async);
  • method:請求方式,如get、post
  • url:請求的url
  • async:是否為異步請求

send

用於發送 HTTP 請求,即調用該方法后HTTP請求才會被真正發出,用法:

xhr.send(param)
  • param:http請求的參數,可以為string、Blob等類型。

abort

用於終止一個ajax請求,調用此方法后readyState將被設置為0,用法:

xhr.abort()

setRequestHeader

用於設置HTTP請求頭,此方法必須在 open() 方法和 send() 之間調用,用法:

xhr.setRequestHeader(header, value);

getResponseHeader

用於獲取http返回頭,如果在返回頭中有多個一樣的名稱,那么返回的值就會是用逗號和空格將值分隔的字符串,用法:

var header = xhr.getResponseHeader(name);

屬性

readyState

用來標識當前XMLHttpRequest對象所處的狀態,XMLHttpRequest對象總是位於下列狀態中的一個:

狀態 描述
0 UNSENT 代理被創建,但尚未調用 open() 方法。
1 OPENED open() 方法已經被調用。
2 HEADERS_RECEIVED send() 方法已經被調用,並且頭部和狀態已經可獲得。
3 LOADING 下載中; responseText 屬性已經包含部分數據。
4 DONE 下載操作已完成。

status

表示http請求的狀態, 初始值為0。如果服務器沒有顯式地指定狀態碼, 那么status將被設置為默認值, 即200。

responseType

表示響應的數據類型,並允許我們手動設置,如果為空,默認為text類型,可以有下面的取值:

描述
"" 將 responseType 設為空字符串與設置為"text"相同, 是默認類型 (實際上是 DOMString)。
"arraybuffer" response 是一個包含二進制數據的 JavaScript ArrayBuffer 。
"blob" response 是一個包含二進制數據的 Blob 對象 。
"document" response 是一個 html Document 或 XML XMLDocument ,這取決於接收到的數據的 MIME 類型。
"json" response 是一個 JavaScript 對象。這個對象是通過將接收到的數據類型視為 JSON 解析得到的。
"text" response 是包含在 DOMString 對象中的文本。

response

返回響應的正文,返回的類型由上面的responseType決定。

withCredentials

ajax請求默認會攜帶同源請求的cookie,而跨域請求則不會攜帶cookie,設置xhr的withCredentials的屬性為true將允許攜帶跨域cookie。

事件回調

onreadystatechange

xhr.onreadystatechange = callback;

當readyState 屬性發生變化時,callback會被觸發。

onloadstart

xhr.onloadstart = callback;

在ajax請求發送之前(readyState==1后, readyState==2前),callback會被觸發。

onprogress

xhr.onprogress = function(event){ console.log(event.loaded / event.total); }

回調函數可以獲取資源總大小total,已經加載的資源大小loaded,用這兩個值可以計算加載進度。

onload

xhr.onload = callback;

當一個資源及其依賴資源已完成加載時,將觸發callback,通常我們會在onload事件中處理返回值。

異常處理

onerror

xhr.onerror = callback;

當ajax資源加載失敗時會觸發callback。

ontimeout

xhr.ontimeout = callback;

當進度由於預定時間到期而終止時,會觸發callback,超時時間可使用timeout屬性進行設置。

 

六、jQuery對Ajax的封裝

在很長一段時間里,人們使用jQuery提供的ajax封裝進行網絡請求,包括$.ajax、$.get、$.post等,這幾個方法放到現在,我依然覺得很實用。

$.ajax({
    dataType: 'json', // 設置返回值類型 contentType: 'application/json', // 設置參數類型 headers: {'Content-Type','application/json'},// 設置請求頭 xhrFields: { withCredentials: true }, // 跨域攜帶cookie data: JSON.stringify({a: [{b:1, a:1}]}), // 傳遞參數 error:function(xhr,status){ // 錯誤處理 console.log(xhr,status); }, success: function (data,status) { // 獲取結果 console.log(data,status); } })

$.ajax只接收一個參數,這個參數接收一系列配置,其自己封裝了一個jqXHR對象,有興趣可以閱讀一下jQuary-ajax 源碼

常用配置:

url

當前頁地址。發送請求的地址。

type

類型:String 請求方式 ("POST" 或 "GET"), 默認為 "GET"。注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。

timeout

類型:Number 設置請求超時時間(毫秒)。此設置將覆蓋全局設置。

success

類型:Function 請求成功后的回調函數。

jsonp

在一個jsonp請求中重寫回調函數的名字。這個值用來替代在"callback=?"這種GET或POST請求中URL參數里的"callback"部分。

error 類型:Function 。請求失敗時調用此函數。

注意:源碼里對錯誤的判定:

isSuccess = status >= 200 && status 300 || status === 304;

返回值除了這幾個狀態碼都會進error回調。

dataType

"xml": 返回 XML 文檔,可用 jQuery 處理。 "html": 返回純文本 HTML 信息;包含的 script 標簽會在插入 dom 時執行。 "script": 返回純文本 JavaScript 代碼。不會自動緩存結果。除非設置了 "cache" 參數。注意:在遠程請求時(不在同一個域下),所有 POST 請求都將轉為 GET 請求。(因為將使用 DOM 的 script標簽來加載) "json": 返回 JSON 數據 。 "jsonp": JSONP 格式。使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數。 "text": 返回純文本字符串

data

類型:String 使用JSON.stringify轉碼

complete

類型:Function 請求完成后回調函數 (請求成功或失敗之后均調用)。

async

類型:Boolean 默認值: true。默認設置下,所有請求均為異步請求。如果需要發送同步請求,請將此選項設置為 false。

contentType

類型:String 默認值: "application/x-www-form-urlencoded"。發送信息至服務器時內容編碼類型。

鍵值對這樣組織在一般的情況下是沒有什么問題的,這里說的一般是,不帶嵌套類型JSON,也就是 簡單的JSON,形如這樣:

{
    a: 1, b: 2, c: 3 }

但是在一些復雜的情況下就有問題了。 例如在 Ajax 中你要傳一個復雜的 json 對像,也就說是對象嵌數組,數組中包括對象,你這樣傳: application/x-www-form-urlencoded 這種形式是沒有辦法將復雜的 JSON 組織成鍵值對形式。

{
  data: { a: [{ x: 2 }] } }

可以用如下方式傳遞復雜的json對象

$.ajax({
    dataType: 'json', contentType: 'application/json', data: JSON.stringify({a: [{b:1, a:1}]}) })

 

七、jQuery的替代者

近年來前端MV*的發展壯大,人們越來越少的使用jQuery,我們不可能單獨為了使用jQuery的Ajax api來單獨引入他,無可避免的,我們需要尋找新的技術方案。

尤雨溪在他的文檔中推薦大家用axios進行網絡請求。axios基於Promise對原生的XHR進行了非常全面的封裝,使用方式也非常的優雅。另外,axios同樣提供了在node環境下的支持,可謂是網絡請求的首選方案。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM