http 總結
http定義
http 是 超文字傳輸協議(HyperTextTransferProtocol)的縮寫,它是網際網路上應用最為廣泛的一種網路協議。
七層網路模型(推薦好文:https://www.cnblogs.com/Robin-YB/p/6668762.html)
OSI七層網路模型 |
TCP/IP四層概念模型 |
對應網路協議 |
應用層(Application) |
應用層 |
HTTP、TFTP,FTP, NFS, WAIS、SMTP |
表示層(Presentation) |
Telnet, Rlogin, SNMP, Gopher |
|
會話層(Session) |
SMTP, DNS |
|
傳輸層(Transport) |
傳輸層 |
TCP, UDP |
網路層(Network) |
網路層 |
IP, ICMP, ARP, RARP, AKP, UUCP |
資料鏈路層(Data Link) |
資料鏈路層 |
FDDI, Ethernet, Arpanet, PDN, SLIP, PPP |
物理層(Physical) |
IEEE 802.1A, IEEE 802.2到IEEE 802.11 |
http三次握手
第一次握手: 客戶端告訴服務端說要建立連線
第二次握手:服務端收到請求後知道有客戶來了,然後就為客戶端開啟tcp socket的埠,開啟後返回給客戶端,返回的ack是客戶端第一次請求過來的seq+1
URI URL URN
URI = Universal Resource Identifier 統一資源標誌符,它包含URL和URN。
URI採用一種特定語法標識一個資源的字串。所標識的資源可能是伺服器上的一個檔案。不過,也可能是一個郵件地址、新聞訊息、圖書、人名、Internet主機或者任何其它內容。
URL = Universal Resource Locator 統一資源定位符
URL唯一地標識一個資源在Internet上的位置。不管用什麼方法表示,只要能定位一個資源,就叫URL。
URN = Universal Resource Name 統一資源名稱
URN它命名資源但不指定如何定位資源,比如:只告訴你一個人的姓名,不告訴你這個人在哪。
三者區別
-
- URI 指的是一個資源
- URL 用地址定位一個資源;
- URN 用名稱定位一個資源。
舉個例子:去尋找一個具體的人(URI);如果用地址:XX省XX市XX區...XX單元XX室的主人 就是URL;如果用身份證號+名字去找就是URN(身份證號+名字 無法確認資源的地址) 。
http報文(好文推薦:https://blog.csdn.net/shouwang666666/article/details/70232053)
請求報文
HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求資料4個部分組成。
請求行包括 請求方法(如:GET、POST等)和http版本組成
請求頭由一系列的鍵值對組成,如User-Agent:xxxx、Content-Type:xxxx等
請求體則是傳輸的資料
一個簡單的請求報文如下:
POST /user HTTP/1.1 //請求行 Host: www.user.com Content-Type: application/x-www-form-urlencoded Connection: Keep-Alive User-agent: Mozilla/5.0. //以上是首部行 (此處必須有一空行) //空行分割header和請求內容 name=world 請求體
響應報文
響應報文由狀態行、響應頭、空行和響應體組成
-
- 狀態行由三部分組成:伺服器HTTP協議版本,響應狀態碼,狀態碼的文字描述,如:HTTP/1.1 200 OK
常見的狀態碼:
200 OK:請求已正常處理。
301 Moved Permanently:資源的uri已更新,永久性重定向
302 Found:資源的URI已臨時定位到其他位置了,臨時性重定向
304 Not Modified:自從上次請求後,請求的網頁未修改過。伺服器返回此響應時,不會返回網頁內容。
400 Bad Request:伺服器端無法理解客戶端傳送的請求,請求報文中可能存在語法錯誤。
401 Unauthorized:未授權,該狀態碼錶示傳送的請求需要有通過HTTP認證(BASIC認證,DIGEST認證)的認證資訊。
403 Forbidden:不允許訪問那個資源。該狀態碼錶明對請求資源的訪問被伺服器拒絕了。(許可權,未授權IP等)
404 Not Found:伺服器上沒有請求的資源。路徑錯誤等。
500 Internal Server Error:貌似內部資源出故障了。該狀態碼錶明伺服器端在執行請求時發生了錯誤。也有可能是web應用存在bug或某些臨時故障。
503 Service Unavailable:抱歉,我現在正在忙著。該狀態碼錶明伺服器暫時處於超負載或正在停機維護,現在無法處理請求
-
- 響應頭由一系列的鍵值對組成,如Connection:keep-alive、Content-Type:xxxx等
- 響應體就是傳輸的資料
CORS跨域請求(好文推薦:http://www.ruanyifeng.com/blog/2016/04/cors.html)
需要瀏覽器和伺服器同時支援,目前幾乎所有的瀏覽器都集成了fetch api,伺服器需要設定介面允許跨域
對CORS來說,分為簡單請求和非簡單請求,簡單請求就直接傳送CORS請求,非簡單請求需要傳送預檢請求並得到肯定答覆後才能傳送正式的請求。
表現形式就是:簡單請求在瀏覽器的network中就只能看到一個請求,非簡單請求在瀏覽器的network中能看到兩個請求
CORS請求的本質:當發現跨域請求是,給請求頭新增Access-Control-Allow-Origin
Cache-Control(好文推薦:https://zhuanlan.zhihu.com/p/79042406)
Cache-Control 是一個 HTTP 協議中關於快取的響應頭,它由一些能夠允許你定義一個響應資源應該何時、如何被快取以及快取多長時間的指令組成。
Cache-Control no-cache
no-chache
使用ETag響應頭來告知客戶端(瀏覽器、代理伺服器)這個資源首先需要被檢查是否在服務端修改過
,在這之前不能被複用。這個意味著no-cache
將會和伺服器進行一次通訊,確保返回的資源沒有修改過,如果沒有修改過,才沒有必要下載這個資源。反之,則需要重新下載。
Cache-Control no-store
no-store
在處理資源不能被快取和複用的邏輯的時候與no-cache
類似,然而,他們之間有一個重要的區別。no-store
要求資源每次都被請求並且下載下來。當在處理隱私資訊(private information)的時候,這是一個重要的特性。
Cache-Control public & private
包含public
指令的響應資源表示允許被任何中間者(可能是代理伺服器、類似於 cdn 網路)快取。這個指令通常不需要在響應頭中用到,因為其他指令已經表明了響應資源是否可以被快取(例如:max-age
)。
private
指令表示響應資源僅僅只能被獲取它的瀏覽器端快取。它不允許任何中間者(intermediate)快取響應的資源。
Cache-Control max-age
這個指令告訴瀏覽器端或者中間者,響應資源能夠在它被請求之後的多長時間以內被複用。例如,max-age
等於 3600 意味著響應資源能夠在接下來的 60 分鐘以內被複用,而不需要從服務端重新獲取。(可以發現,max-age
的單位是秒)
Cache-Control s-maxage
s-maxage
與上文提到的max-age
類似,這裡的“s”代表共享,並且,這個指令一般用於代理伺服器。這個指令會覆蓋max-age
和expires
響應頭。
Cache-Control no-transform
中間代理有時會改變圖片以及檔案的格式,從而達到提高效能的效果。no-transform
指令告訴中間代理不要改變資源的格式。
Last-Modified和Etag
- Last-Modified 上次修改時間,配合If-Modified-Since或者If-Unmodifiled-Since使用,對比上次修改時間已驗證資源是否需要更新
- Etage 資料簽名,配合If-Match或者If-Non-Match使用,對比資源的簽名判斷是否使用快取
- 設定了etag、last-modified後,瀏覽器在第二次發起請求後就會把if-none-match和if-modified-since帶上
ETag是HTTP1.1中才加入的一個屬性,用來幫助伺服器控制Web端的快取驗證。它的原理是這樣的,當瀏覽器請求伺服器的某項資源(A)時, 伺服器根據A算出一個雜湊值(3f80f-1b6-3e1cb03b)並通過 ETag 返回給瀏覽器,瀏覽器把"3f80f-1b6-3e1cb03b" 和 A 同時快取在本地,當下次再次向伺服器請求A時,會通過類似 If-None-Match: "3f80f-1b6-3e1cb03b" 的請求頭把ETag傳送給伺服器,伺服器再次計算A的雜湊值並和瀏覽器返回的值做比較,如果發現A發生了變化就把A返回給瀏覽器(200),如果發現A沒有變化就給瀏覽器返回一個304未修改。這樣通過控制瀏覽器端的快取,可以節省伺服器的頻寬,因為伺服器不需要每次都把全量資料返回給客戶端。
注:HTTP中並沒有指定如何生成ETag,雜湊是比較理想的選擇。
通常情況下,ETag更類似於資源指紋(fingerprints),如果資源發生變化了就會生成一個新的指紋,這樣可以快速的比較資源的變化。在伺服器端實現中,很多情況下並不會用雜湊來計算ETag,這會嚴重浪費伺服器端資源,很多網站預設是禁用ETag的。有些情況下,可以把ETag退化,比如通過資源的版本或者修改時間來生成ETag。
如果通過資源修改時間來生成ETag,那麼效果和HTTP協議裡面的另外一個控制屬性(Last-Modified)就雷同了,使用 Last-Modified 的問題在於它的精度在秒(s)的級別,比較適合不太敏感的靜態資源。
cookie和session
cookie:
服務端返回資料時通過set-Cookie設定到瀏覽器內,瀏覽器儲存cookie後,在同域的訪問內下次請求會自動帶上
cookie可以以陣列的形式設定多個:'Set-Cookie':['id=123','abc=456']
cookie可以設定過期時間:'Set-Cookie':['id=123;max-age=10','abc=456']
max-age:有效期多長
expires:到期的具體時間
如未設定過期時間,則瀏覽器關閉後消失
設定HttpOnly後,瀏覽器無法通過document.cookie讀取該cookie
domain:訪問域設定
cookie只能一個域內訪問
a.com不能訪問b.com下的cookie
domain設定可以讓a.test.com能夠訪問test.com下的cookie
不能跨域設定cookie,只能一級設定二級,使所有一級域名下的二級域名都可以訪問該一級域名下的cookie
session:
Session是另一種記錄客戶狀態的機制,不同的是Cookie儲存在客戶端瀏覽器中,而Session儲存在伺服器上。客戶端瀏覽器訪問伺服器的時候,伺服器把客戶端資訊以某種形式記錄在伺服器上。這就是Session。客戶端瀏覽器再次訪問時只需要從該Session中查詢該客戶的狀態就可以了。
http長連線
- 從 HTTP/1.1起,預設使用長連線,用以保持連線特性。使用長連線的HTTP協議,會在響應頭有加入這行程式碼:Connection:keep-alive
- 在使用長連線的情況下,當一個網頁開啟完成後,客戶端和伺服器之間用於傳輸HTTP資料的 TCP連線不會關閉,如果客戶端再次訪問這個伺服器上的網頁,會繼續使用這一條已經建立的連線。Keep-Alive不會永久保持連線,它有一個保持時間,可以在不同的伺服器軟體中設定這個時間。
- 長連結可以設定timeout
- 同個tcp內是有先後順序的
- chrome瀏覽器可以併發6個tcp
- Connection:keep-alive(長)、close(短)
- http2:通道複用 ,同域下,tcp併發傳送http請求
CSP:Content-Security-Policy(內容安全策略)
default-src 全侷限制'Content-Security-Policy':'default-src http: https:' //只加載外鏈資源 'Content-Security-Policy':'default-src \'self\'' //只加載同域下的外鏈資源(包括圖片等所有資源) 'Content-Security-Policy':'script-src \'self\'' //只加載同域下的script資源 'Content-Security-Policy':'default-src \'self\' https://cdn.bootcss.com' //只加載同域或指定域名下的外鏈資源 'Content-Security-Policy':'default-src \'self\'; form-action \'self\'' //只加載同域下的外鏈資源,form表單只能提交到本地 'Content-Security-Policy':'acript-src \'self\'; form-action \'self\'; report-uri /report' //將不符合條件的資源請求提交報告給伺服器/report地址下(資源請求被block掉) 'Content-Security-Policy-Report-Only':'acript-src \'self\'; form-action \'self\'; report-uri /report' //將不符合條件的資源提交報告給伺服器/report地址下(資源請求不被block掉)