一、第一個問題
http相關一個最經典的問題:瀏覽器輸入URL後HTTP請求返回的完整過程
ps:瀏覽器中的performance會記錄整個過程中各個階段所要花費的時間。- 第一步會做一個redirect(跳轉),瀏覽器可能記錄了這個地址以及永久跳轉成一個新的地址,所以第一步瀏覽器先回判斷需不需要這個redirect以及跳轉到哪裡。
- 第二部會看快取(app cache),判斷這個頁面是不是已經快取過了,如果有快取就讀取快取,沒有的話就要去伺服器請求資源了。
- DNS查詢(域名解析),去找到這個域名所對應的IP地址。
- 建立TCP連線,會涉及三次握手,有可能是HTTPS會跟HTTP有所不同。
- request(傳送請求)
- response(結束相應)
二、HTTP協議基礎及發展歷史
網路協議分層
- 物理層主要作用是定義物理裝置如何傳輸資料
- 資料鏈路層在通訊的實體間建立資料鏈路連線
- 網路層為資料在結點之間傳輸建立邏輯鏈路
- 傳輸層
- 向使用者提供可靠的端到端(End-to-End)服務
- 傳輸層向高層遮蔽了下層資料通訊的細節
- 應用層
- 為應用軟體提供了很多服務
- 構建於TCP協議之上
- 遮蔽網路傳輸相關細節
HTTP協議發展歷史
- HTTP/0.9
- 只有GET命令
- 沒有HEADER等描述資料的資訊
- 伺服器傳送相應完畢後,就關閉TCP連線
- HTTP/1.0
- 增加了很多命令
- 增加status code和header
- 多字符集支援、多部分傳送、許可權、快取等
- HTTP/1.1(目前)、HTTPS與HTTP1.1類似
- 持久連線,通過宣告可以保持(不關閉TCP連線)
- pipeline(同一個連線裡傳送多個請求)
- 增加了host(同一個伺服器可以跑多個服務)和其他一些命令
- https 公鑰加密,私鑰解密,中間人沒有私鑰
- HTTP2
- 所有資料以二進位制傳輸
- 同一個連線裡面傳送多個請求不再需要按照順序來(併發)
- 頭資訊壓縮以及推送等提高效率的功能
HTTP的三次握手
- 三次握手的作用:可以避免服務端開啟一些無用的連線
HTTPS握手過程
URI、URL、URN
- URI
- 統一資源標示符
- 用來唯一標識網際網路上的資訊資源
- 包括URL和URN
- URL
- 統一資源定位器
- user:pass@host.com:80/path?query=…
- 此類格式的都叫做URL,比如ftp協議
- URN
- 永久統一資源定位符
- 在資源移動之後還能被找到
- 目前沒有非常成熟的使用方案
HTTP報文
- HTTP方法
- 用來定義對資源的操作
- 常用的GET/POST等
- 從定義上講有各自的語義
- HTTP CODE
- 定義伺服器對請求的處理結果
- 各個區間的CODE有各自的語義
- 好的HTTP服務可以通過CODE判斷結果
三、HTTP各種特性總覽
CORS跨域請求的限制與解決
- 需要後端支援:'Access-Control-Allow-Origin':'*'
- 預請求:'Access-Control-Allow-Headers':'自定義的頭'
- 允許的方法:'Access-Control-Allow-Methods':'POST,PUT,DELETE'
- 在一定時間內不需要預請求:'Access-Control-Max-Age': '1000' 1000s內不用預請求
http快取頭cache-control
- 可快取性
- public 都可以進行快取,下一次可以讀快取不需要再請求
- private 發起請求的瀏覽器才可以請求
- no-cache 任何一個結點都不可以,需要經過伺服器的驗證
- 到期
- max-age=
- s-maxage= 代理伺服器會讀取s-message代替max-age
- max-stale= 發起端設定的,即便max-age已經過期了,瀏覽器還是讀取這個已經過期的快取
- 重新驗證
- must-revalidate 在設定了max-age的快取當中,如果已經過期了,必須去原服務端去傳送這個請求重新獲取資料
- must-revalidate 用在快取伺服器上的
- 其他
- no-store 永遠不能快取
- no-transform 不允許隨意改變內容
- 重新整理瀏覽器快取通過hash碼
資源驗證
驗證頭:驗證快取Last-Modified和Etag的使用- Last-Modified
- 上次修改時間
- 配合If-Modified-Since或者If-Unmodified-Since使用
- 對比上次修改時間以驗證資源是否需要更新
- Etag
- 資料簽名
- 配合If-Match或者If-Non-Match使用
- 對比資源的簽名判斷是否使用快取
cookie與session
- cookie
- 通過Set-Cookie設定
- 下次請求會自動帶上
- 鍵值對,可以設定多個
- cookie屬性
- max-age和expires設定過期時間
- Secure只在https的時候傳送
- HttpOnly無法通過document.cookie訪問(可防止csrf攻擊)
HTTP長連線
- 一個tcp/ip連線最多允許6個併發請求
- Connection: keep-alive持久連線,單個請求完畢後不會關閉tcp/ip連線
- http2可以在一個tcp/ip連線上併發請求(序列與並行的區別)
資料協商
- 分類
- 請求
- Accept
- Content
- 返回
- 請求
- 請求中通過Accept來進行宣告想要什麼樣的資料
- Accept 制定的資料型別
- Accept-Encoding 編碼方式,限制壓縮方式
- Accept-Language 語言
- User-Agent 瀏覽器相關資訊
- 服務端返回的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;
}
}
複製程式碼