HTTP協議知識總結

ChenXiaoSong12321發表於2018-09-04

一、第一個問題

http相關一個最經典的問題:瀏覽器輸入URL後HTTP請求返回的完整過程

瀏覽器輸入URL後HTTP請求返回的完整過程
ps:瀏覽器中的performance會記錄整個過程中各個階段所要花費的時間。

  1. 第一步會做一個redirect(跳轉),瀏覽器可能記錄了這個地址以及永久跳轉成一個新的地址,所以第一步瀏覽器先回判斷需不需要這個redirect以及跳轉到哪裡。
  2. 第二部會看快取(app cache),判斷這個頁面是不是已經快取過了,如果有快取就讀取快取,沒有的話就要去伺服器請求資源了。
  3. DNS查詢(域名解析),去找到這個域名所對應的IP地址。
  4. 建立TCP連線,會涉及三次握手,有可能是HTTPS會跟HTTP有所不同。
  5. request(傳送請求)
  6. response(結束相應)

二、HTTP協議基礎及發展歷史

網路協議分層

經典五層模型

  1. 物理層主要作用是定義物理裝置如何傳輸資料
  2. 資料鏈路層在通訊的實體間建立資料鏈路連線
  3. 網路層為資料在結點之間傳輸建立邏輯鏈路
  4. 傳輸層
    • 向使用者提供可靠的端到端(End-to-End)服務
    • 傳輸層向高層遮蔽了下層資料通訊的細節
  5. 應用層
    • 為應用軟體提供了很多服務
    • 構建於TCP協議之上
    • 遮蔽網路傳輸相關細節

HTTP協議發展歷史

  1. HTTP/0.9
    • 只有GET命令
    • 沒有HEADER等描述資料的資訊
    • 伺服器傳送相應完畢後,就關閉TCP連線
  2. HTTP/1.0
    • 增加了很多命令
    • 增加status code和header
    • 多字符集支援、多部分傳送、許可權、快取等
  3. HTTP/1.1(目前)、HTTPS與HTTP1.1類似
    • 持久連線,通過宣告可以保持(不關閉TCP連線)
    • pipeline(同一個連線裡傳送多個請求)
    • 增加了host(同一個伺服器可以跑多個服務)和其他一些命令
    • https 公鑰加密,私鑰解密,中間人沒有私鑰
  4. HTTP2
    • 所有資料以二進位制傳輸
    • 同一個連線裡面傳送多個請求不再需要按照順序來(併發)
    • 頭資訊壓縮以及推送等提高效率的功能

HTTP的三次握手

TCP連線

三次握手順序

  • 三次握手的作用:可以避免服務端開啟一些無用的連線

HTTPS握手過程

HTTP協議知識總結

URI、URL、URN

  1. URI
    • 統一資源標示符
    • 用來唯一標識網際網路上的資訊資源
    • 包括URL和URN
  2. URL
  3. URN
    • 永久統一資源定位符
    • 在資源移動之後還能被找到
    • 目前沒有非常成熟的使用方案

HTTP報文

HTTP報文

  1. HTTP方法
    • 用來定義對資源的操作
    • 常用的GET/POST等
    • 從定義上講有各自的語義
  2. HTTP CODE
    • 定義伺服器對請求的處理結果
    • 各個區間的CODE有各自的語義
    • 好的HTTP服務可以通過CODE判斷結果

三、HTTP各種特性總覽

CORS跨域請求的限制與解決

  1. 需要後端支援:'Access-Control-Allow-Origin':'*'
  2. 預請求:'Access-Control-Allow-Headers':'自定義的頭'
  3. 允許的方法:'Access-Control-Allow-Methods':'POST,PUT,DELETE'
  4. 在一定時間內不需要預請求:'Access-Control-Max-Age': '1000' 1000s內不用預請求

http快取頭cache-control

  1. 可快取性
    • public 都可以進行快取,下一次可以讀快取不需要再請求
    • private 發起請求的瀏覽器才可以請求
    • no-cache 任何一個結點都不可以,需要經過伺服器的驗證
  2. 到期
    • max-age=
    • s-maxage= 代理伺服器會讀取s-message代替max-age
    • max-stale= 發起端設定的,即便max-age已經過期了,瀏覽器還是讀取這個已經過期的快取
  3. 重新驗證
    • must-revalidate 在設定了max-age的快取當中,如果已經過期了,必須去原服務端去傳送這個請求重新獲取資料
    • must-revalidate 用在快取伺服器上的
  4. 其他
    • no-store 永遠不能快取
    • no-transform 不允許隨意改變內容
  5. 重新整理瀏覽器快取通過hash碼

資源驗證

驗證快取
驗證頭:驗證快取Last-Modified和Etag的使用

  1. Last-Modified
    • 上次修改時間
    • 配合If-Modified-Since或者If-Unmodified-Since使用
    • 對比上次修改時間以驗證資源是否需要更新
  2. Etag
    • 資料簽名
    • 配合If-Match或者If-Non-Match使用
    • 對比資源的簽名判斷是否使用快取

cookie與session

  1. cookie
    • 通過Set-Cookie設定
    • 下次請求會自動帶上
    • 鍵值對,可以設定多個
  2. cookie屬性
    • max-age和expires設定過期時間
    • Secure只在https的時候傳送
    • HttpOnly無法通過document.cookie訪問(可防止csrf攻擊)

HTTP長連線

  1. 一個tcp/ip連線最多允許6個併發請求
  2. Connection: keep-alive持久連線,單個請求完畢後不會關閉tcp/ip連線
  3. http2可以在一個tcp/ip連線上併發請求(序列與並行的區別)

資料協商

  1. 分類
    • 請求
      1. Accept
      2. Content
    • 返回
  2. 請求中通過Accept來進行宣告想要什麼樣的資料
    • Accept 制定的資料型別
    • Accept-Encoding 編碼方式,限制壓縮方式
    • Accept-Language 語言
    • User-Agent 瀏覽器相關資訊
  3. 服務端返回的content
    • Content-Type
    • Content-Encoding
    • Content-Language

Redirect

if (request.url === '/') {
    response.writeHead(302, {  // or 301 永久變成了新的路徑
      'Location': '/new'
    })
    response.end()
  }
  if (request.url === '/new') {
    response.writeHead(200, {
      'Content-Type': 'text/html',
    })
    response.end('<div>this is content</div>')
  }
複製程式碼

一個簡單的https的nginx配置

proxy_cache_path cache levels=1:2 keys_zone=my_cache:10m; #nginx代理快取

server {
  listen       80;
  # listen       [::]:80 default_server;
  server_name  test.com;

  # return 302 https://$server_name$request_uri;

  location / {
    proxy_cache my_cache;
    proxy_pass http://127.0.0.1:8888;
    proxy_set_header Host $host;
  }
}

server {
  listen       443 http2; # http2
  server_name  test.com;

  # http2_push_preload  on; # http2

  ssl on;
  ssl_certificate_key  ../certs/localhost-privkey.pem;
  ssl_certificate      ../certs/localhost-cert.pem;

  location / {
    proxy_cache my_cache;
    proxy_pass http://127.0.0.1:8888;
    proxy_set_header Host $host;
  }
}
複製程式碼

相關文章