基礎概念:
URL:
uri包含url和urn。目前web只有url比較流行。
- URI: 統一資源標識符
- URL:統一資源定位符
- URN:統一資源名稱
請求和相應報文:
請求報文:
響應報文:
HTTP方法:
客戶端發送的請求報文 第一行 爲請求行,包含了方法字段。
get:獲取資源
當前網絡中絕大部分請求是get方法。
head: 獲取報文首部
和get方法一樣,但是不返回報文實體的主體部分。
主要用於確認URL的有效性以及資源更新的日期時間等。
post: 傳輸實體的主體
post請求主要用來傳輸數據,而get請求主要用來獲取資源。 下文有
具體比較。
put:上傳文件
由於自身不帶驗證機制,任何人都可以上傳文件,存在安全性問題,一般不使用該方法。
patch:對資源進行部分修改:
put也可以用於修改資源,但是隻能完全替代原始資源,patch允許部分修改。
delete :刪除文件:
與put功能相反,並且不帶驗證機制,任何人都能刪。
DELETE /file.html HTTP/1.1
options :支持查詢的方法
查詢指定的url能夠支持的方法。會返回Allow:GET,POST.,OPTIONS 等這樣的內容。
connect:要求在與代理服務器通信時建立隧道
使用SSL和TLS協議把通信內容加密後經網絡隧道傳輸。
CONNECT WWW.CSDN.COM:433 HTTP/1.1
TRACE :追蹤路徑
服務器會將通信路徑返回給客戶端。
發送請求時,在MAX-Forwords首部字段中填入數值,每經過一個服務器就會減1,當數值爲0時就會停止傳輸。
通常不會使用TRACE,並且其容易受到XST攻擊(跨站追蹤)
HTTP狀態碼:
服務器返回的響應報文的第一行爲狀態行,包含了狀態碼以及原因短語,用來告知客戶端請求的結果。
1xx開頭 : 信息
- 100 Continue: 表明到目前爲止都很正常。
2xx開頭 : 成功
- 200 OK
- 204 No content: 請求已經成功處理,但是返回的響應報文不包含實體的主體部分。一般在只需要從客戶端給服務端發送消息,而不需要返回數據時使用。
3xx開頭:重定向
- 301 :永久性重定向
- 302 :臨時重定向
- 303 : 臨時性重定向,但是明確要求客戶端應該採用get方法獲取資源。
4xx開頭:客戶端錯誤
- 400 :請求報文中存在語法錯誤
- 401 :該狀態碼錶示發送的請求需要認證信息(BASIC認證,DIGEST認證)。 如果之前進行過一次認證,則表示用戶認證失敗。
- 403 :請求被拒絕
- 404 :沒有發現url對應的ip
5xx 服務器錯誤:
- 500 : 服務器正在執行請求時發生錯誤。
- 503: 服務器暫時處理超負荷或者停機維護狀態,無法處理請求。
HTTP首部:
有四種類型的首部字段:通用首部字段,請求首部字段,響應首部字段,實體首部字段。
通用首部字段
請求首部字段
響應首部字段:
實體首部字段
具體應用
Cookie
HTTP協議是無狀態的,主要是爲了讓HTTP協議儘可能簡單,使得它能夠處理大量事務。http/1.1引入了cookie來保存狀態信息。
Cookie是服務器發送到用戶瀏覽器並保存到本地的一小塊數據,它會在瀏覽器之後向同一服務器發起請求時被攜帶上,用於告知服務端兩個請求是否來自於同一個服務器。由於每次都需要攜帶cookie數據,因此會帶來額外的性能開銷,尤其在移動環境下。
cookie曾一度用於客戶端數據的存儲,因爲當時並沒有其它合適的存儲辦法而作爲唯一的存儲手段。但是現在瀏覽器支持各種各樣的存儲方式,cookie漸漸被淘汰。新的瀏覽器API已經允許開發者將數據存儲到本地,如使用web storage API(本地存儲和會話存儲)或indexedDB 。
用途:
- 會話狀態管理 :如用戶登陸狀態,購物車,遊戲分數或其它需要記錄的信息。
- 個性化設置:用戶自定義設置,主題等。
- 瀏覽器行爲追蹤:跟蹤分析用戶行爲。
創建過程:
服務器發送的響應報文段包含set-cookie首部字段,客戶端得到響應報文後把Cookie內容保存到瀏覽器中。
客戶端之後對同一服務器發送請求時,會從瀏覽器中取出Cookie信息並通過cookies請求首部字段發送給服務器。
分類:
- 會話期cookie: 瀏覽器關閉後被自動刪除,也就是說僅在會話期有效。
- 持久性cookie: 指定一個特定的過期時間(expires)或者有效期(max-age)之後就成爲了持久性的
JS中如何獲取Cookie
通過Document.cookie 屬性可創建新的Cookie,也可通過該屬性訪問非HttpOnly標記的Cookie
document.cookie="yummy_cookie=choco";
document.cookie="tasty_cookie=strawberry";
console.log(document.cookie);
Secure和HttpOnly
標記爲secure的cookie只能通過被https協議加密過的請求發送給服務端。但即便設置了secure標記,敏感信息也不該通過cookie傳輸,因爲Cookie有其固有的不安全性,secure標記也無法提供確實的安全保障。
標記爲httponly的cookie不能爲js腳本所調用。跨站腳本攻擊(XSS)經常使用JS的Document.cookie API來竊取用戶的Cookie信息,因此一定程度避免XSS攻擊。
作用域:
Domain標識 指定了哪些主機可以接收Cookie。如果不指定,默認當前文檔主機(不包含子域名)。如果指定了Domain,則一般包含子域名。
如設置Domain=csdn.net則cookie也包含在子域名 如mp.csdn.net中
Path標識 指定了主機下的哪些路徑可以接收Cookie(該URL路徑必須存在於請求URL中)。已字符(/)作爲路徑分割符,子路徑也會被匹配。
Session
除了將用戶信息通過Cookie存儲在用戶瀏覽器中,也可以利用Session存儲在服務器端。存儲在服務器端的信息更安全。
Session可以存儲在服務器上的文件,數據庫或者內存中。也可以將 Session存儲在redis中,這樣效率會更高。
使用Session維護用戶登陸狀態的過程:
- 用戶進行登錄時,用戶提交包含用戶名和密碼的表單,放入HTTP請求報文中;
- 服務器驗證該用戶名和密碼;
- 如果正確把該用戶信息存儲到redis中,它在redis中的key稱SessionID
- 服務器返回的響應報文的Set-cookie首部字段包含了這個SessionID,客戶端收到響應報文之後將該報文存入瀏覽器中。
- 客戶端之後對同一個服務器進行請求時會包含該Cookie值,服務器收到後會取出SessionID,從redis中取出用戶信息,執行業務操作。
需要注意SessionID的安全問題,不能讓它被惡意攻擊者輕易獲取,那麼就不能產生一個容易被猜到的SessionID。此外,還需要經常重新生成SessionID。在對安全性要求極高的場景下,如支付操作,除了使用SessionID管理用戶狀態之外,還需要對用戶進行重新驗證。如驗證碼等形式。
瀏覽器禁用Cookie
此時就無法使用Cookie來保存用戶信息,只能使用Session。除此之外,不能再將SessionID存放到Cookie中。而是使用URL重寫技術,將SessionID 作爲URL的參數進行傳遞。
Cookie與Session的選擇
- Cookie只能存儲ASCII碼字符串,爲Session可以存取任何類型的數據,因此再考慮數據複雜性時首選Session;
- Cookie存儲在瀏覽器中,容易被而已查看。如果非要將一些隱私數據存在cookie中,可以將Cookie值進行加密,然後在服務器進行解密。
- 對於大型網站,如果用戶所有信息都存儲在Session中,那麼開銷是非常大的,因此不建議將所有用戶的信息存儲到Session中。
緩存:
優點:
- 緩解服務器壓力
- 降低客戶端獲取資源的延遲:緩存通常位於內存中,讀取緩存速度更快。並且緩存在地理位置上也可能比源服務器來的近,例如瀏覽器緩存。
實現方法:
- 讓代理服務器進行緩存
- 讓客戶端瀏覽器進行緩存
Cache-Control
Http/1.1 通過cache-Control首部字段來控制緩存。
禁止進行緩存
no-store指令規定不能對請求或響應的任何一部分進行緩存。
cache-control:no-store
強制確認緩存:
no-cache指令規定緩存服務器需要先向源服務器驗證緩存資源的有效性,只有當緩存資源有效才能使用該緩存對客戶端進行響應。
Cache-Control:no-cache
私有緩存和公共緩存
private指令規定了將資源作爲私有緩存,只能被單獨用戶所使用,一般存儲在用戶瀏覽器中。
cache-control:private
public指令規定了資源將作爲公共緩存,可以被多個用戶所使用,一般存儲在代理服務器中。
cache-control:public
緩存過期機制:
max-age指令出現在請求報文中,並且緩存資源的緩存時間小於該指令指定的時間,那個就能接收該緩存。
max-age指令出現在響應報文中,表示緩存資源在緩存服務器中保存的時間。
cache-control:max-age=31536000
expires首部字段也可以用於告知緩存服務器該資源什麼時候會過期。
- 在http/1.1中,會優先處理max-age指令。
- 在http/1.0中,max-age指令會被忽略掉。
緩存驗證
需要先了解Etag首部字段的含義,它是資源的唯一標識。url不能唯一表示資源。如http://www.google.com/ 有中文和英文兩個資源,只有Etag才能對這兩個資源進行唯一標識。
可以將緩存資源的Etag值放入If-None-Match首部,服務器收到該請求後,判斷緩存資源的Etag值和資源的最新ETag值是否一致,如果一致則表示緩存資源有效。
Last-Modified首部字段也可以用於緩存驗證,它包含在源服務器發送的響應報文中,指示源服務器對資源的最後修改時間。但是它是一種弱校驗器,只能精確到一秒,一般都是Etag的備用方案。如果響應首部字段裏包含這個信息,客戶端可以在後續的請求中帶上If-Modified-Since來驗證。服務器只在所請求的資源在給定日期時間之後在對內容進行過修改的情況下才會返回資源。如果請求的資源從那時起未經修改,那麼返回一個不帶消息主體的304
連接管理
短連接與長連接
當瀏覽器訪問一個包含多張圖片的html頁面時,除了請求訪問的html頁面資源,還會請求圖片資源。如果每進行一次http通信就要新建一個tcp連接,那麼開銷會很大。
長連接只需要建立一次tcp連接就能進行多次http通信。
- 從http/1.1開始默認是長連接的,如果要斷開連接,需要由客戶端或者服務器端提出斷開,使用
Connection:close;
- 在http1.1 之前是默認是短連接的,如果需要使用長連接,需要由客戶端使用
Connection:keep-alive
流水線:
默認情況下,http請求是按順序發出的,下一個請求只有在當前請求收到響應之後纔會被髮出。由於會受到網絡延遲和帶寬的限制,在下一個請求被髮送到服務器之前,可能需要等待很長時間。
流水線是在同一條長連接上發出連續的請求,而不用等待響應返回,這樣可以避免連接延遲。
內容協商
類型
1,服務端驅動型
客戶端設置特定的https首部字段,如Accept,Aceept-Charset,Accept-Encoding,Accept-Language,Content-Languag,服務器根據這些字段返回特定的資源。
它存在如下問題:
- 服務器很難知道客戶端瀏覽器的全部信息。
- 客戶端提供的信息相當冗餘(http/2 協議的首部壓縮機制緩解了這個問題) 並且存在隱私風險(http指紋識別技術)
- 給定的資源需要返回不同的展現形式,共享緩存的效率會降低,而服務端實現會越來越複雜。
2,代理驅動型
服務器返回300 或者 406 客戶端會從中選最合適的那個資源。
Vary
Vary:accept-Language
在使用內容協商的情況下,只有當緩存服務器中緩存內容滿足協商條件時,源服務器返回的響應包含vary:accept-language內容,緩存服務器對這個響應進行緩存之後,在客戶端下一次訪問同一個url資源,並且accept-language與緩存中的對應的值相同時纔會返回該該緩存。
內容編碼
內容編碼將實體主體進行壓縮,從而減少傳輸的數據量。
常用的內用編碼有:gzip,compress,deflate,identity。
瀏覽器發送Accept-Encoding首部,其中包含有它所支持的壓縮算法,以及各自的優先級。服務器則從選擇一種,使用該算法對響應的消息主體進行壓縮,並且發送content-encoding首部來告知瀏覽器,服務器選擇了哪一種算法。由於該內容協商過程時基於編碼類型來選擇資源的展現形似的,在響應的Vary首部至少要包含Conntent-encoding。
範圍請求:
如果網絡出現中斷,服務器只發送了一部分數據,範圍請求可以使客戶端只請求服務器未發送的那部分數據,而從避免服務器重新發送所有數據。
1,Range
在請求報文中添加Range首部字段指定請求的範圍。
請求成功,服務器返回的響應包含206狀態碼。
2,Accept-Ranges
響應首部字段Accept-Ranges用於告知客戶端是否能夠處理範圍請求,可以處理使用bytes,否則使用none。
3,響應狀態碼
- 在請求成功的情況下,服務器會206
- 在請求返回越界的請求下,服務器會返回416
- 在不支持範圍請求的情況下,服務器返回200OK狀態碼。
多部分對象集合
一份報文主體可包含有多種類型的實體同時發送,每個實體之間用boundary字段定義的分隔符進行分割,每個部分都可以有首部字段。
如上傳多個表單時可以使用如下方式。
虛擬主機
http/1.1 使用虛擬主機技術,使得一臺服務器擁有多個域名,並且在邏輯上可以看成多個服務器。
通信數據轉發
1,代理
代理服務器接收客戶端的請求,並且轉發給其它服務器。
使用代理的主要目的:
- 緩存
- 負載均衡
- 網絡訪問控制
- 訪問日誌記錄
代理服務器分正向代理和反向代理兩種:
- 用戶察覺得到正向代理得存在。
- 反向代理一般位於內部網絡中,用戶察覺不到。
2,網關
與代理服務器不同的是,網關服務器會將http轉換爲其它協議進行通信,從而請求其它非http服務器的服務。
3,隧道
使用SSL等加密手段,在客戶端和服務器之間建立一條安全的通信線路。