HTTP是基於客戶端/服務端(C/S)的架構模型,經過一個可靠的連接來交換信息,是一個無狀態的請求/響應協議。css
HTTP是一種可以獲取如 HTML 這樣的網絡資源的 protocol(通信協議)。它是在 Web 上進行數據交換的基礎,是一種 client-server 協議,也就是說,請求一般是由像瀏覽器這樣的接受方發起的。html
客戶端和服務端經過交換各自的消息(與數據流正好相反)進行交互。由像瀏覽器這樣的客戶端發出的消息叫作 requests,被服務端響應的消息叫作 responses。web
HTTP是無鏈接的:
無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。 一個鏈接是由傳輸層來控制的,這從根本上不屬於HTTP的範圍。HTTP並不須要其底層的傳輸層協議是面向鏈接的,只須要它是可靠的,或不丟失消息的(至少返回錯誤)。HTTP是可擴展的:
在 HTTP/1.0 中出現的 HTTP headers 讓協議擴展變得很是容易。只要服務端和客戶端就新 headers 達成語義一致,新功能就能夠被輕鬆加入進來。HTTP是無狀態:
HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。 使用Cookies能夠建立有狀態的會話。HTTP請求報文由:請求行、請求頭部、空行和請求數據四個部分組成。
複製代碼
HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。
複製代碼
根據HTTP標準,HTTP請求可使用多種請求方法。算法
HTTP1.0定義了三種請求方法:GET
, POST
, HEAD
方法。數據庫
HTTP1.1新增了五種請求方法:OPTIONS
, PUT
, DELETE
, TRACE
, CONNECT
方法。跨域
方法 | 描述 |
---|---|
GET | 請求獲取Request-URI所標識的資源。 |
HEAD | 相似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭。 |
POST | 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件),數據被包含在請求體中。POST請求可能會致使新的資源的創建和/或已有資源的修改。 |
PUT | 從客戶端向服務器傳送的數據取代指定的文檔的內容。 |
DELETE | 請求服務器刪除 Request-URI 所標識的資源。 |
CONNECT | HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器,主要使用SSL和TLS將數據加密後經過網絡隧道進行傳輸。 |
OPTIONS | 使服務器傳回該資源所支持的全部HTTP請求方法。用 * 來代替資源名稱,向 Web 服務器發送 OPTIONS 請求,能夠測試服務器功能是否正常運做。 |
TRACE | 回顯服務器收到的請求,主要用於測試或診斷。 |
其中,最多見的是 GET 和 POST 方法,若是是 RESful
接口的話通常會用到 PUT、DELETE、GET、POST(分別對應增刪查改)瀏覽器
主要分爲通用首部、請求首部、響應首部和實體首部四種:緩存
首部字段名 | 說明 |
---|---|
Cache-Control | 控制緩存行爲。 |
Connection | 管理持久鏈接,設置其值爲Keep-Alive可實現長鏈接。 |
Date | 建立HTTP報文的日期和時間。 |
Pragma | Http/1.1以前的歷史遺留字段,僅做爲HTTP/1.0向後兼容而定義,雖然是通用字段,當一般被使用在客戶單的請求中,如Pragma: no-cache, 表示客戶端在請求過程當中不循序服務端返回緩存的數據。 |
Trailer | 報文尾部的首部。 |
Transfer-Encoding | 規定了傳輸報文主題時使用的傳輸編碼,如Transfer-Encoding: chunked。 |
Upgrade | 用於檢查HTTP協議或其餘協議是否有可以使用的更高版本。 |
Via | 追蹤客戶端和服務端之間的報文的傳輸路徑,還可避免會環的發生,因此在通過代理時必須添加此字段。 |
Warning | Http/1.1的報文字段,從Http/1.0的AfterRetry演變而來,用來告知用戶一些與緩存相關的警告信息。 |
首部字段名 | 說明 |
---|---|
Accept | 客戶端可以處理的媒體類型 |
Accept-Charset | 表示客戶端支持的字符集。例如:Accept-Charset: GB2312, ISO-8859-1 |
Accept-Encoding | 表示客戶端支持的內容編碼格式。如:Accept-Encoding:gzip |
Accept-Language | 表示客戶端支持的語言。如:Accept-Language: zh-cn, en |
Authorization | 表示客戶端的認證信息。客戶端在訪問須要認證的也是時,服務器會返回401,隨後客戶端將認證信息加在Authorization字段中發送到服務器後,若是認證成功,則返回200 |
Host | 表示訪問資源所在的主機名,即URL中的域名部分。如:m.baidu.com |
If-Match | If-Match的值與所請求資源的ETag值(實體標記,與資源相關聯。資源變化,實體標記跟着變化)一致時,服務器才處理此請求 |
If-Modified-Since | 用於確認客戶端擁有的本地資源的時效性 |
If-None-Match | If-Match的值與所請求資源的ETag值不一致時服務器才處理此請求 |
If-Range | If-Range的值(ETag值或時間)與所訪問資源的ETag值或時間相一致時,服務器處理此請求,並返回Range字段中設置的指定範圍的數據。若是不一致,則返回全部內容。If-Range其實算是If-Match的升級版,由於它的值不匹配時,依然可以返回數據,而If-Match不匹配時,請求不會被處理,須要數據時需再次進行請求 |
If-Unmodified-Since | 與If-Modified-Since相反,表示請求的資源在指定的時間以後未發生變化時,才處理請求,不然返回412 |
Max-Forwards | 表示請求可通過的服務器的最大數目,請求每被轉發一次,Max-Forwards減1,當Max-Forwards爲0時,所在的服務器將再也不轉發,而是直接作出應答。經過此字段可定位通訊問題 |
Proxy-Authorization | 當客戶端接收到來自代理服務器的認證質詢時,客戶端會將認證信息添加到Proxy-Authorization來完成認證。與Authorization相似,只不過Authorization是發生在客戶端與服務端之間 |
Range | 獲取部分資源,例如:Range: bytes=500-1000表示獲取指定資源的第500到1000字節之間的內容,若是服務器可以正確處理,則返回206做爲應答,表示返回了部分數據,若是不能處理這種範圍請求,則以200做爲應答,返回完整的數據 |
Referer | 告知服務器請求是從哪一個頁面發起的 |
User-Agent | 將發起請求的瀏覽器和代理名稱等信息發送給服務端 |
Cookie | 在請求時添加Cookie, 以實現HTTP的狀態記錄 |
首部字段名 | 說明 |
---|---|
Accept-Ranges | 是否接受字節範圍。 |
Age | 服務端告知客戶端,源服務器(而不是緩存服務器)在多久以前建立了響應,單位爲秒。 |
ETag | 實體資源的標識,可用來請求指定的資源。 |
Location | 請求的資源所在的新位置。 |
Proxy-Authenticate | 將代理服務器須要的認證信息發送給客戶端。 |
Retry-After | 服務端告知客戶端多久以後再重試,通常與503和3xx重定向類型的應答一塊兒使用。 |
Server | 告知服務端當前使用的HTTP服務器應用程序的相關信息。 |
Vary | 代理服務器緩存的管理信息。 |
WWW-Authenticate | 告知客戶端適用於所訪問資源的認證方案,如Basic或Digest。401的響應中確定帶有WWW-Authenticate字段。 |
Set-Cookie | 服務器經過此字段給客戶端傳遞Cookie信息。 |
首部字段名 | 說明 |
---|---|
Allow | 通知客戶端,服務器所支持的請求方法。 |
Content-Encoding | 告知客戶端,服務器對資源的內容編碼。 |
Content-Language | 告知客戶端,資源所使用的天然語言。 |
Content-Length | 告知客戶端資源的長度 |
Content-Location | 告知客戶端資源所在的位置。 |
Content-Type | 告知客戶端資源的媒體類型,取值同請求首部字段中的Accept。 |
Expires | 告知客戶端資源的失效日期。可用於對緩存的處理。 |
Last-Modified | 告知客戶端資源最後一次修改的時間。 |
X-Frame-Options:首部字段X-Frame-Options屬於HTTP響應首部 用於控制網站內容在其餘Web網站的Frame標籤內的顯示問題,主要目的是爲了防止點擊劫持攻擊服務器
X-XSS-Protection:首部字段X-XSS-Protection屬於HTTP響應首部 針對跨站腳本攻擊的一種對策,用於控制瀏覽器XSS防禦機制的開關cookie
DNT(Do Not Track):拒絕我的信息被收集,表示拒絕被精準廣告追蹤的一種方法
狀態碼負責表示客戶端請求的返回結果、標記服務器端是否正常、通知出現的錯誤。
狀態碼 | 類別 | 分類描述 |
---|---|---|
1XX | Informational(信息性狀態碼) | 請求正在被處理 |
2XX | Success(成功狀態碼) | 請求處理成功 |
3XX | Redirection(重定向狀態碼) | 須要進行重定向 |
4XX | Client Error(客戶端錯誤狀態碼) | 服務器沒法處理請求 |
5XX | Server Error(服務器錯誤狀態嗎) | 服務器處理請求時出錯 |
狀態碼 | 短句 | 含義 |
---|---|---|
100 | Continue | 繼續,客戶端應繼續其請求 |
101 | Switching Protocols | 切換協議,只能切換到更高級的協議 |
狀態碼 | 短句 | 含義 |
---|---|---|
200 | OK | 請求成功,通常用於GET與POST請求 |
201 | Created | 已建立,成功請求並建立了新的資源 |
202 | Accepted | 已接受,已經接受請求,但未處理完成 |
狀態碼 | 短句 | 含義 |
---|---|---|
300 | Multiple Choices | 多種選擇,請求的資源可包括多個位置 |
301 | Moved Permanently | 永久移動 |
302 | Found | 臨時移動,GET 或者 HEAD 請求 |
303 | See Other | 查看其它地址,與302相似。需使用GET請求查看 |
304 | Not Modified | 未修改,服務器返回此狀態碼時,不會返回任何資源 |
307 | Temporary Redirect | 臨時重定向,不應改變請求方法 |
狀態碼 | 短句 | 含義 |
---|---|---|
400 | Bad Request | 客戶端請求的語法錯誤,服務器沒法理解 |
401 | Unauthorized | 請求要求用戶的身份認證 |
402 | Payment Required | 保留,未來使用 |
403 | Forbidden | 服務器理解請求客戶端的請求,可是拒絕執行此請求 |
404 | Not Found | 服務器沒法根據客戶端的請求找到資源(網頁) |
405 | Method Not Allowed | 客戶端請求中的方法被禁止 |
狀態碼 | 短句 | 含義 |
---|---|---|
500 | Internal Server Error | 服務器內部錯誤,沒法完成請求 |
501 | Not Implemented | 服務器不支持請求的功能,沒法完成請求 |
502 | Bad Gateway | 從遠程服務器接收到了一個無效的響應 |
503 | Service Unavailable | 服務器暫時的沒法處理客戶端的請求 |
504 | Gateway Time-out | 未及時從遠端服務器獲取請求 |
505 | HTTP Version not supported | 服務器不支持請求的HTTP協議的版本,沒法完成處理 |
Content-Type,內容類型,通常是指網頁中存在的Content-Type,用於定義網絡文件的類型和網頁的編碼,決定瀏覽器將以什麼形式、什麼編碼讀取這個文件。
常見的媒體類型: 文本文件:text/html, text/plain, text/css, application/xml 圖片文件:iamge/jpeg, image/gif, image/png; 視頻文件:video/mpeg 應用程序使用的二進制文件:application/octet-stream, application/zip
經常使用的內容編碼: gzip: 由文件壓縮程序gzip生成的編碼格式; compress: 由Unix文件壓縮程序compress生成的編碼格式; deflate: 組合使用zlib和deflate壓縮算法生成的編碼格式; identity:默認的編碼格式,不執行壓縮。
Cookie主要用於如下三個方面:
Cookie曾一度用於客戶端數據的存儲,因當時並無其它合適的存儲辦法而做爲惟一的存儲手段,但如今隨着現代瀏覽器開始支持各類各樣的存儲方式,Cookie漸漸被淘汰。因爲服務器指定Cookie後,瀏覽器的每次請求都會攜帶Cookie數據,會帶來額外的性能開銷(尤爲是在移動環境下)。新的瀏覽器API已經容許開發者直接將數據存儲到本地,如使用 Web storage API (本地存儲和會話存儲)或 IndexedDB 。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
(1) 會話期Cookie 瀏覽器關閉以後它會被自動刪除,也就是說它僅在會話期內有效。
(2) 持久性Cookie 和關閉瀏覽器便失效的會話期Cookie不一樣,持久性Cookie能夠指定一個特定的過時時間(Expires)或有效期(Max-Age)。
(3) Secure 和 HttpOnly
標記爲 Secure
的Cookie只應經過被HTTPS協議加密過的請求發送給服務端。
爲避免跨域腳本 (XSS) 攻擊,經過JavaScript的 Document.cookie API沒法訪問帶有 HttpOnly
標記的Cookie,它們只應該發送給服務端。
(4) Cookie的做用域 Domain 和 Path 標識定義了Cookie的做用域:即Cookie應該發送給哪些URL。
鏈接管理是一個 HTTP 的關鍵話題:打開和保持鏈接在很大程度上影響着網站和 Web 應用程序的性能。在 HTTP/1.x 裏有多種模型:短鏈接
, 長鏈接
, 和 HTTP 流水線
。
短鏈接 HTTP 最先期的模型,也是 HTTP/1.0 的默認模型,是短鏈接。每個 HTTP 請求都由它本身獨立的鏈接完成;這意味着發起每個 HTTP 請求以前都會有一次 TCP 握手,並且是接二連三的。
長鏈接 一個長鏈接會保持一段時間,重複用於發送一系列請求,節省了新建 TCP 鏈接握手的時間,還能夠利用 TCP 的性能加強能力。固然這個鏈接也不會一直保留着:鏈接在空閒一段時間後會被關閉(服務器可使用 Keep-Alive
協議頭來指定一個最小的鏈接保持時間)。
HTTP 流水線 HTTP 流水線在現代瀏覽器中並非默認被啓用的 HTTP/2 流水線已經被更好的算法給代替,如 multiplexing
域名分片
除非你有緊急而迫切的需求,不要使用這一過期的技術,升級到 HTTP/2 就行了。在 HTTP/2 裏,作域名分片就不必了:HTTP/2 的鏈接能夠很好的處理併發的無優先級的請求。域名分片甚至會影響性能。大多數 HTTP/2 的實現還會使用一種稱做鏈接凝聚的技術去嘗試合併被分片的域名。
若是服務器端想要更快速的響應網站或應用程序的應答,它能夠迫使客戶端創建更多的鏈接。
瀏覽器有併發限制,是爲了防止Dos/DDoS
攻擊。
例如,不要在同一個域名下獲取全部資源,假設有個域名是www.example.com
咱們能夠把它拆分紅好幾個域名:www1.example.com、www2.example.com 全部這些域名都指向同一臺服務器,瀏覽器會同時爲每一個域名創建多條鏈接。
這一技術被稱做域名分片(域名發散)
域名收斂
就是將靜態資源放在一個域名下,減小DNS解析的開銷。
重用已獲取的資源可以有效的提高網站與應用的性能。Web 緩存可以減小延遲與網絡阻塞,進而減小顯示某個資源所用的時間。藉助 HTTP 緩存,Web 站點變得更具備響應性。
緩存是一種保存資源副本並在下次請求時直接使用該副本的技術。當 web 緩存發現請求的資源已經被存儲,它會攔截請求,返回該資源的拷貝,而不會去源服務器從新下載。
私有與共享緩存
。共享緩存存儲的響應可以被多個用戶使用,私有緩存只能用於單獨用戶。下文將主要介紹瀏覽器緩存
,除此以外還有代理緩存、網關緩存、CDN、反向代理緩存和負載均衡器等部署在服務器上,爲站點和 web 應用提供更好的穩定性、性能和擴展性。
常見的 HTTP 緩存只能存儲 GET
響應,對於其餘類型的響應則無能爲力。
爲了方便理解,咱們認爲瀏覽器存在一個緩存數據庫,用於存儲緩存信息(實際上靜態資源是被緩存到了內存和磁盤中),在瀏覽器第一次請求數據時,此時緩存數據庫沒有對應的緩存數據,則須要請求服務器,服務器會將緩存規則和數據返回,瀏覽器將緩存規則和數據存儲進緩存數據庫。
咱們能夠將其分爲兩大類強緩存
、協商緩存
瀏覽器若是判斷本地緩存未過時,就直接使用,無需發起http請求(200 from memory/disk cache)
HTTP 1.0
服務器使用的響應頭字段爲 Expires
,值爲將來的絕對時間(時間戳),瀏覽器請求時的當前時間超過了 Expires 設置的時間,表明緩存失效,須要再次向服務器發送請求,不然都會直接從緩存數據庫中獲取數據。
HTTP 1.1
Cache-Control
是最重要的規則,默認爲private。
private 私有緩存 public 共享緩存 max-age 緩存的內容將在 xxx 秒後失效 no-cache 須要使用對比緩存來驗證緩存數據 no-store 全部內容都不會緩存,強緩存、協商緩存都不會觸發
注意:在 HTTP 1.0 版本中,Expires
字段的絕對時間是從服務器獲取的,因爲請求須要時間,因此瀏覽器的請求時間與服務器接收到請求所獲取的時間是存在偏差的,這也致使了緩存命中的偏差,在 HTTP 1.1 版本中,由於 Cache-Control
的值 max-age=xxx
中的 xxx 是以秒爲單位的相對時間,因此在瀏覽器接收到資源後開始倒計時,規避了 HTTP 1.0 中緩存命中存在偏差的缺點,爲了兼容低版本 HTTP 協議,正常開發中兩種響應頭會同時使用,HTTP 1.1 版本的實現優先級高於 HTTP 1.0
。
瀏覽器第一次請求數據時,服務器會將緩存標識與數據一塊兒返回給客戶端,客戶端將兩者備份至緩存數據庫中。再次請求數據時,客戶端將備份的緩存標識發送給服務器,服務器根據緩存標識進行判斷,判斷成功後,返回304
狀態碼,通知客戶端比較成功,可使用緩存數據。
HTTP 1.0
If-Modified-Since
,而服務端的是Last-Modified
,它的做用是,在發起請求時,若是If-Modified-Since和Last-Modified匹配,那麼表明服務器資源並未改變,所以服務端不會返回資源實體,而是隻返回頭部,通知瀏覽器可使用本地緩存。Last-Modified,顧名思義,指的是文件最後的修改時間,並且只能精確到1s之內
。HTTP 1.1
If-None-Match
,而服務端的是E-tag
,一樣,發出請求後,若是If-None-Match和E-tag匹配,則表明內容未變,通知瀏覽器使用本地緩存,和Last-Modified不一樣,E-tag更精確,它是相似於指紋同樣的東西,基於FileEtag INode Mtime Size
生成,只要文件變,指紋就會變,並且沒有1s精確度的限制
。爲了使緩存策略更加健壯、靈活,HTTP 1.0 版本 和 HTTP 1.1 版本的緩存策略會同時使用,甚至強制緩存和協商緩存也會同時使用,對於強制緩存,服務器通知瀏覽器一個緩存時間,在緩存時間內,下次請求,直接使用緩存,超出有效時間,執行協商緩存策略,對於協商緩存,將緩存信息中的 Etag 和 Last-Modified 經過請求頭 If-None-Match 和 If-Modified-Since 發送給服務器,由服務器校驗同時設置新的強制緩存,校驗經過並返回 304 狀態碼時,瀏覽器直接使用緩存,若是協商緩存也未命中,則服務器從新設置協商緩存的標識。
Vary HTTP 響應頭決定了對於後續的請求頭,如何判斷是請求一個新的資源仍是使用緩存的文件。
當緩存服務器收到一個請求,只有當前的請求和原始(緩存)的請求頭跟緩存的響應頭裏的Vary都匹配,才能使用緩存的響應。
使用vary頭有利於內容服務的動態多樣性。例如,使用Vary: User-Agent頭,緩存服務器須要經過UA判斷是否使用緩存的頁面。若是須要區分移動端和桌面端的展現內容,利用這種方式就能避免在不一樣的終端展現錯誤的佈局。另外,它能夠幫助 Google 或者其餘搜索引擎更好地發現頁面的移動版本,而且告訴搜索引擎沒有引入Cloaking。
參考文章: