【芝士整理】網絡請求相關

計算機網絡結構

物理層

定義物理設備標準,起到傳輸比特流的做用。javascript

數據鏈路層

提供可靠的經過物理介質傳輸數據的方法。html

經過差錯控制、流量控制方法將有差錯的物理鏈路(物理鏈路容易受到干擾)變爲無差錯的數據鏈路java

將物理層的比特流數據封裝成數據幀傳遞給上層,將上層的數據幀轉換爲比特流給物理層。node

提供MAC地址(物理地址),可做爲局域網內一個網卡的惟一標識。ios

網絡層

解決不一樣子網間的通訊問題:邏輯尋址,規定不一樣的信息交換方式,路由算法,鏈接服務。git

IP協議

網絡上每個節點都有一個獨立的邏輯地址——IP地址es6

IP協議負責將數據包傳送到目的地,沒有提供一種數據未傳達之後的處理機制(這被認爲是上層協議須要作的事情),是不可靠的協議。github

傳輸層

提供可靠的端到端的差錯和流量控制,保證報文的正確傳輸web

UDP協議

沒有創建鏈接,直接向對象發包,不可靠但快速高效。應用:ping命令、實時音視頻通訊ajax

TCP協議

  • 三次握手創建鏈接
  • 發送方給接受方TCP數據報,而後等待對方的確認TCP數據報,若是沒有,就從新發,若是有,就發送下一個數據報。
  • 接受方等待發送方的數據報,若是獲得數據報並檢驗無誤,就發送ACK(確認)數據報,並等待下一個TCP數據報的到來。直到接收到FIN(發送完成數據報)
  • 四次揮手停止鏈接

會話層

創建和管理應用程序之間的通訊,保證應用程序自動收發包和尋址

表示層

解釋不一樣系統之間的通訊語法

應用層

直接面向用戶的程序或服務

HTTP協議

什麼是HTTP協議?

基於TCP/IP協議基礎的一個應用層協議,用於從Web服務器傳輸超文本到本地瀏覽器的傳送協議,由請求和響應構成。

HTTP協議的特色

無狀態:請求相互獨立,通訊狀態不被保存

HTTP報文的組成

HTTP報文包括請求報文和響應報文兩大部分,其中請求報文由請求行(request line)、請求頭(header)、空行和請求體四個部分組成。而響應報文由狀態行、響應頭部、空行和響應體四個部分組成。

HTTP請求方式

GET, HEAD, POST, PUT, DELETE,OPTIONS

HEAD:獲取報頭。

OPTIONS:獲取請求資源的選項、需求或服務器支持,並不是資源請求。ajax請求跨域資源時,使用OPTIONS方法發送嗅探請求,以判斷是否有對指定資源的訪問權限。

GET和POST的區別

  • GET安全性低,會被緩存
  • GET請求在URL中顯示參數,POST請求在send中傳遞參數

狀態碼

1xx:表示請求已接收,繼續處理

2xx:成功,操做被成功接收並處理

3xx:重定向,須要進一步的操做以完成請求

4xx:客戶端錯誤,請求有語法錯誤或請求沒法實現

5xx:服務端錯誤,服務器端錯誤--服務器未能實現合法的請求

  • 200 請求正常處理
  • 204 請求正常處理但沒有資源返回
  • 301永久性重定向
  • 302 臨時性重定向
  • 304 指採用GET方法的請求報文中包含if-matched,if-modified-since,if-none-match,if-range,if-unmodified-since任一個首部)服務器端容許請求訪問資源,但因發生請求未知足條件的狀況後,直接返回304Modified
  • 400 請求報文中有語法錯誤
  • 401 表示未受權
  • 403 請求被服務器拒絕
  • 404 服務器上沒法找到請求的資源
  • 500 服務器在執行時發生錯誤
  • 503 服務器暫時處於超負載或正在進行停機維護

請求API

Ajax

var xhr = null;
if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
    xhr.open("POST","test.html",true);  
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");  
    xhr.send("fname=Henry&lname=Ford"); 
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.responseText);
        }
    }
    xhr.onerror = function (e) {
        console.log(e)
    }
}

readyState

  • 0:未初始化,還沒有調用open
  • 1:已經調用open,還沒有調用send
  • 2:已經send,但還沒有收到響應
  • 3:已接收到部分響應
  • 4:已收到全部響應

error事件

Network error,只有發生網絡層的錯誤纔會出發error事件, 應用層的錯誤不會進入error

onload事件

當請求成功完成時觸發,此時xhr.readyState=4

onabort事件

調用xhr.abort()後觸發

withCredentials

在跨域請求中,客戶端必須手動設置 xhr.withCredentials=true,且服務器端也必須容許親貴能攜帶認證信息(即響應頭中包含 Access-Control-Allow-Credentials:true),這樣瀏覽器纔會自動將 cookie加在 請求頭中。

另外,要特別注意一點,一旦跨域請求可以攜帶認證信息,服務器端必定不能將Access-Control-Allow-Origin設置爲*,而必須設置爲請求頁面的域名。

XMLHttpRequest的具體介紹

Fetch

Fetch API 基於Promise設計,fetch()返回一個Promise對象

fetch(url).then(response => response.json())
  .then(data => console.log(data))
  .catch(e => console.log("Oops, error", e))

Fetch原生支持率並不高,須要引入各類polyfill

  1. 因爲 IE8 是 ES3,須要引入 ES5 的 polyfill: es5-shim, es5-sham
  2. 引入 Promise 的 polyfill: es6-promise
  3. 引入 fetch 探測庫:fetch-detector
  4. 引入 fetch 的 polyfill: fetch-ie8
  5. 可選:若是你還使用了 jsonp,引入 fetch-jsonp
  6. 可選:開啓 Babel 的 runtime 模式,如今就使用 async/await

Fetch polyfill 的基本原理是探測是否存在 window.fetch 方法,若是沒有則用 XHR 實現。這也是 github/fetch 的作法,可是有些瀏覽器(Chrome 45)原生支持 Fetch,但響應中有中文時會亂碼,老外又不太關心這種問題,因此我本身才封裝了 fetch-detectorfetch-ie8 只在瀏覽器穩定支持 Fetch 狀況下才使用原生 Fetch。這些庫如今 天天有幾千萬個請求都在使用,絕對靠譜

Fetch 常見坑

  • Fetch 請求默認是不帶 cookie 的,須要設置 fetch(url, {credentials: 'include'})
  • 服務器返回 400,500 錯誤碼時並不會 reject,只有網絡錯誤這些致使請求不能完成時,fetch 纔會被 reject。

引用自傳統 Ajax 已死,Fetch 永生

axios

基於Promise的HTTP封裝庫,可用於瀏覽器和node環境

  • 瀏覽器中使用XMLHttpRequest
  • node.js中使用http模塊
  • 支持Promise API
  • 可攔截請求和響應
  • 轉換請求和響應數據
  • 可取消請求
  • 自動轉換JSON數據
  • 爲客戶端提供XSRF支持

axios項目倉庫&文檔

跨域

什麼是跨域

跨域的解決方法

緩存

強緩存

不會發出請求,直接從緩存中讀取數據

Expires

設置過時時間,缺點使用瀏覽器時間判斷,瀏覽器時間會隨客戶端設置修改

Cache-Control

設置相對時間,以秒爲單位

Cache-Control優先級大於Expires

協商緩存

發出請求,與服務端配合判斷資源是否過時,須要與Cache-Control共同使用

若是命中協商緩存,服務端返回304並通知瀏覽器從本地緩存讀取資源

Last-Modified和If-Modified-Since

記錄和比較資源的修改時間,存在的問題:1. 時間偏差 2. 資源修改和時間修改可能不一致

ETag和If-None-Match

服務端經過哈希算法根據文件內容計算出哈希值

記錄和比較資源的哈希值

ETag優先級大於Last-Modified

用戶行爲對緩存的影響

  1. 地址欄訪問,連接跳轉是正經常使用戶行爲,將會觸發瀏覽器緩存機制;
  2. F5刷新,瀏覽器會設置max-age=0,跳過強緩存判斷,會進行協商緩存判斷;
  3. ctrl+F5刷新,跳過強緩存和協商緩存,直接從服務器拉取資源。

其餘響應頭

no-cache

是否使用緩存須要通過協商緩存來驗證決定

no-store

全部內容都不會被緩存,即不使用強制緩存,也不使用協商緩存

public

全部內容都將被緩存(客戶端和代理服務器均可緩存)

private

全部內容只有客戶端能夠緩存

請求優化

  • 資源壓縮合並
  • 非核心代碼異步加載
  • 利用瀏覽器緩存
  • 使用CDN
  • 預解析DNS

頁面性能優化辦法有哪些

相關文章
相關標籤/搜索