【相關推薦:、】
2005年,Jesse James Garrett撰寫了一篇文章《Ajax - A New Approach to Web Applications》,這篇文章中描繪了一個被稱為Ajax(Asynchronous JavaScript+XML,即非同步JavaScript+XML)的技術。這個技術涉及傳送伺服器請求額外資料而不重新整理頁面,從而實現更好地使用者體驗。Garrett解釋了這個技術怎樣改變自Web誕生以來就一直延續的傳統單擊等待的模式。
把Ajax推到歷史舞臺上的關鍵技術是XMLHttpRequest(XHR)物件。在XHR出現之前,Ajax風格的通訊必須通過一些黑科技實現,主要是使用隱藏的窗格或內嵌窗格。XHR為傳送伺服器請求和獲取相應提供了合理的介面。這個介面可以實現非同步從伺服器獲取額外資料,意味著使用者不用頁面重新整理也可以獲取資料。通過XHR物件獲取資料後,可以使用DOM方法把資料插入網頁。
XHR物件的API被普遍認為比較難用,而Fetch API自動誕生以後迅速成為了XHR更現代的替代標準,Fetch API支援期約promise和服務執行緒(service worker),已經成為及其強大的Web開發工具。
通過XHR進行Ajax通訊的一個主要限制是跨源安全策略。預設情況下,XHR只能存取與發起請求的頁面在同一域內的資源。這個安全限制可以防止某些惡意行為。不過,瀏覽器也需要支援合法跨源存取的能力。
跨源資源共用(CORS,Cross-Origin Rerource Sharing)定義了瀏覽器與伺服器如何實現跨源通訊。CORS背後的基本思路就是使用自定義的HTTP頭部允許瀏覽器和伺服器相互瞭解,以確定請求或相應應該成功還是失敗。
對於簡單的請求,比如GET或POST請求,沒有自定義頭部,而且請求體是text/plain型別,這樣的請求在傳送時會有一個額外的頭部叫Origin。Origin頭部包含傳送請求的頁面的源(協定、域名、埠),以便伺服器確定是否為其提供響應。
現代瀏覽器通過XMLHttpRequst物件原生支援CORS,在嘗試存取不同源的資源時,這個行為會被自動觸發。要向不同域的源傳送請求,可以使用標準XHR物件並給open()方法傳入一個絕對URL,比如:
let xhr = new XMLHttpRequest();xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.reaponseText); }else{ alert("Request was unsuccessful:"+xhr.status); } }};xhr.open("get","http://www.nezha.con/page/",true);xhr.send(null);
跨域XHR物件允許存取status和statusText屬性,也允許同步請求,出於安全考慮,跨域XHR物件也施加了一些額外的限制。
不能使用setRequestHeader()設定自定義頭部;
不能傳送和接收cookie;
getAllResponseHeaders()方法始終返回空字串;
因為無論同域還是跨域請求都是用同一個介面,所以最好在存取本地資源時使用相對URL,在存取遠端資源時使用絕對URL,這樣可以更明確地區分使用場景,同時避免出現存取本地資源時出現頭部或cookie資訊存取受限的問題。
CORS通過一種叫預檢請求的伺服器驗證機制,允許使用自定義頭部、除GET和POST之外的方法,以及不同請求體內容型別。在要傳送涉及上述某種高階選項的請求時,會先想伺服器傳送一個預檢請求。這個請求使用OPTIONS方法傳送幷包含如下頭部:
Origin:與簡單請求相同;
Access-Control-Request-Method:請求希望使用的方法;
Access-Control-Request-Headers:(可選)要使用的逗號分隔的自定義頭部列表;
Fetch API能夠執行XMLHttpRequest物件的所有任務,但更容易使用,介面也更現代化,能夠在Web工作執行緒等Web工具中使用。XMLHttpRequest可以選擇非同步,而Fetch API則必須是非同步。
fetch()方法是暴露在全域性作用域中的,包括主頁面執行執行緒、模組和工作執行緒。呼叫這個方法,瀏覽器就會向給定URL傳送請求。
1、分派請求
fetch()只有一個必需的引數input。多數情況下,這個引數是獲取資源的URL,這個方法返回一個期約:
let r = fetch('/bar');console.log(r);//Promise<pending>
URL的格式(相對路徑、絕對路徑等)的解釋與XHR物件一樣。
請求完成、資源可用時,期約會解決一個Response物件,這個物件是API的封裝,可以通過它取得相應資源。獲取資源要使用這個物件的屬性和方法,掌握響應的情況並將負載均衡轉為有用的形式。
2、讀取響應
讀取響應內容的最簡單方式是取得純文字格式的內容,只要用到text()方法。這個方法返回一個期約,會解決為取得資源的完整內容。
3、處理狀態碼和請求失敗
Fetch API 支援通過Response的status和statusText屬性檢查響應狀態。成功獲取響應的請求通常會產生值為200的狀態碼。
4、常見Fetch請求模式
傳送JSON資料
在請求體中傳送引數
傳送檔案
載入Blob檔案
傳送跨域請求
中斷請求
通訊端websocket的目標是通過一個長時連線實現與伺服器全雙工、雙向的通訊。在JavaScript中建立websocket時,一個HTTP請求會傳送到伺服器以初始化連線。伺服器響應後,連線使用HTTP中的Upgrade頭部從HTTP協定切換到websocket協定,這意味著websocket不能通過標準HTTP伺服器實現,而必須使用支援該協定的專有伺服器。
因為websocket使用了自定義協定,所以URL方案稍有變化,不能再使用http://或https://,而要使用ws://和wss://。前者是不安全的連線,後者是安全連線。在執行websocket URL時,必須包含URL方案,因為將來有可能再支援其他方案。
使用自定義協定而非HTTP協定的好處是,使用者端與伺服器質檢可以傳送非常少的資料,不會對HTTP造成任何負擔。使用更小的封包讓websocket非常適合寬頻和延遲問題比較明顯的移動應用。使用自定義協定的缺點是,定義協定的時間比定義JavaScript API的時間要長,websocket得到了所有主流瀏覽器的支援。
【相關推薦:、】
以上就是JavaScript詳細解析之網路請求與遠端資源的詳細內容,更多請關注TW511.COM其它相關文章!