HTTP有哪些⽅法?
HTTP1.0定義了三種請求⽅法: GET, POST 和 HEAD⽅法
HTTP1.1新增了五種請求⽅法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT
這些⽅法的具體作⽤是什麼?
GET: 通常⽤於請求伺服器傳送某些資源
HEAD: 請求資源的頭部資訊, 並且這些頭部與 HTTP GET ⽅法請求時返回的⼀致. 該請求⽅法的⼀個使⽤場景是在下載⼀個⼤⽂件前先獲取其⼤⼩再決定是否要下載, 因此可以節約頻寬資源
OPTIONS: ⽤於獲取⽬的資源所⽀持的通訊選項
POST: 傳送資料給伺服器
PUT: ⽤於新增資源或者使⽤請求中的有效負載替換⽬標資源的表現形式
PATCH: ⽤於對資源進⾏部分修改
CONNECT: HTTP/1.1協議中預留給能夠將連線改為管道⽅式的代理伺服器TRACE: 回顯伺服器收到的請求,主要⽤於測試或診斷
GET和POST有什麼區別?
資料傳輸⽅式不同:GET請求透過URL傳輸資料,⽽POST的資料透過請求體傳輸。
安全性不同:POST的資料因為在請求主體內,所以有⼀定的安全性保證,⽽GET的資料在URL中,通過歷史記錄,快取很容易查到資料資訊。
資料型別不同:GET只允許 ASCII 字元,⽽POST⽆限制
GET⽆害: 重新整理、後退等瀏覽器操作GET請求是⽆害的,POST可能重複提交表單
特性不同:GET是安全(這⾥的安全是指只讀特性,就是使⽤這個⽅法不會引起伺服器狀態變化)且冪等(冪等的概念是指同⼀個請求⽅法執⾏多次和僅執⾏⼀次的效果完全相同),⽽POST是⾮安全⾮冪等
PUT和POST都是給伺服器傳送新增資源,有什麼區別?
PUT 和POST⽅法的區別是,PUT⽅法是冪等的:連續調⽤⼀次或者多次的效果相同(⽆副作⽤),⽽POST⽅法是⾮冪等的。
除此之外還有⼀個區別,通常情況下,PUT的URI指向是具體單⼀資源,⽽POST可以指向資源集合。
舉個例⼦,我們在開發⼀個部落格系統,當我們要建立⼀篇⽂章的時候往往⽤ POST https://www.jianshu.com/articles , 這個請求的語義是,在articles的資源集合下建立⼀篇新的⽂章,如果我們多次提交這個請求會建立多個⽂章,這是⾮冪等的。
⽽ PUT https://www.jianshu.com/articles/820357430 的語義是更新對應⽂章下的資源(⽐如修改作者名稱等),這個
URI指向的就是單⼀資源,⽽且是冪等的,⽐如你把『劉德華』修改成『蔡徐坤』,提交多少次都是修改成『蔡徐坤』
ps: 『POST表示建立資源,PUT表示更新資源』這種說法是錯誤的,兩個都能建立資源,根本區別就在於冪等性
PUT和PATCH都是給伺服器傳送修改資源,有什麼區別?
PUT和PATCH都是更新資源,⽽PATCH⽤來對已知資源進⾏區域性更新。
⽐如我們有⼀篇⽂章的地址 https://www.jianshu.com/articles/820357430 ,這篇⽂章的可以表示為:
當我們要修改⽂章的作者時,我們可以直接傳送 PUT https://www.jianshu.com/articles/820357430 ,這個時候的資料應該是:
這種直接覆蓋資源的修改⽅式應該⽤put,但是你覺得每次都帶有這麼多⽆⽤的資訊,那麼可以傳送 PATCH https://www.jianshu.com/articles/820357430 ,這個時候只需要:
http的請求報⽂是什麼樣的?
請求報⽂有4部分組成: 請求⾏
請求頭部空⾏
請求體
請求⾏包括:請求⽅法欄位、URL欄位、HTTP協議版本欄位。它們⽤空格分隔。例如,GET /index.html HTTP/1.1。
請求頭部:請求頭部由關鍵字/值對組成,每⾏⼀對,關鍵字和值⽤英⽂冒號“:”分隔
User-Agent:產⽣請求的瀏覽器型別。
Accept:客戶端可識別的內容型別列表。
Host:請求的主機名,允許多個域名同處⼀個IP地址,即虛擬主機。
請求體: post put等請求攜帶的資料
http的響應報⽂是什麼樣的?
請求報⽂有4部分組成:
響應⾏響應頭空 ⾏ 響應體
響應⾏: 由協議版本,狀態碼和狀態碼的原因短語組成,例如 HTTP/1.1 200 OK 。響應頭:響應部⾸組成
響應體:伺服器響應的資料
聊⼀聊HTTP的部⾸有哪些?
內容很多,重點看標『✨ 』內容
通⽤⾸部欄位(General Header Fields):請求報⽂和響應報⽂兩⽅都會使⽤的⾸部Cache-Control 控制快取 ✨
Connection 連線管理、逐條⾸部 ✨
Upgrade 升級為其他協議via 代理伺服器的相關資訊Wraning 錯誤和警告通知
Transfor-Encoding 報⽂主體的傳輸編碼格式 ✨
Trailer 報⽂末端的⾸部⼀覽
Pragma 報⽂指令
Date 建立報⽂的⽇期
請求⾸部欄位(Reauest Header Fields):客戶端向伺服器傳送請求的報⽂時使⽤的⾸部Accept 客戶端或者代理能夠處理的媒體型別 ✨
Accept-Encoding 優先可處理的編碼格式Accept-Language 優先可處理的⾃然語⾔Accept-Charset 優先可以處理的字符集If-Match ⽐較實體標記(ETage) ✨
If-None-Match ⽐較實體標記(ETage)與 If-Match相反 ✨
If-Modified-Since ⽐較資源更新時間(Last-Modified)✨
If-Unmodified-Since⽐較資源更新時間(Last-Modified),與 If-Modified-Since相反 ✨
If-Rnages 資源未更新時傳送實體byte的範圍請求
Range 實體的位元組範圍請秋 ✨
Authorization web的認證資訊 ✨
Proxy-Authorization 代理伺服器要求web認證資訊
Host 請求資源所在伺服器 ✨
From ⽤戶的郵箱地址
User-Agent 客戶端程式資訊 ✨ Max-Forwrads 最⼤的逐跳次數TE 傳輸編碼的優先順序
Referer 請 求 原 始 放 的 url Expect 期待伺服器的特定⾏為
響應⾸部欄位(Response Header Fields):從伺服器向客戶端響應時使⽤的欄位
Accept-Ranges 能接受的位元組範圍Age 推算資源建立經過時間Location 令客戶端重定向的URI ✨ vary 代理伺服器的快取資訊
ETag 能夠表示資源唯⼀資源的字串 ✨
WWW-Authenticate 伺服器要求客戶端的驗證資訊Proxy-Authenticate 代理伺服器要求客戶端的驗證資訊Server 伺服器的資訊 ✨
Retry-After 和狀態碼503 ⼀起使⽤的⾸部欄位,表示下次請求伺服器的時間
實體⾸部欄位(Entiy Header Fields):針對請求報⽂和響應報⽂的實體部分使⽤⾸部
Allow 資源可⽀持http請求的⽅法 ✨ Content-Language 實體的資源語⾔Content-Encoding 實體的編碼格式Content-Length 實體的⼤⼩(位元組) Content-Type 實體媒體型別
Content-MD5 實體報⽂的摘要Content-Location 待 替 資 源 的 yri Content-Rnages 實體主體的位置返回Last-Modified 資源最後的修改資源 ✨ Expires 實體主體的過期資源 ✨
聊⼀聊HTTP的狀態碼有哪些?
2XX 成功
200
OK,表示從客戶端發來的請求在伺服器端被正確處理 ✨
201
Created 請求已經被實現,⽽且有⼀個新的資源已經依據請求的需要⽽建⽴
202
Accepted 請求已接受,但是還沒執⾏,不保證完成請求
204 No content,表示請求成功,但響應報⽂不含實體的主體部分206 Partial Content,進⾏範圍請求 ✨
3XX 重定向
301 moved permanently,永久性重定向,表示資源已被分配了新的 URL 302 found,臨時性重定向,表示資源臨時被分配了新的 URL ✨
303
see other,表示資源存在著另⼀個 URL,應使⽤ GET ⽅法丁⾹獲取資源
304
not modified,表示伺服器允許訪問資源,但因發⽣請求未滿⾜條件的情況
307 temporary redirect,臨時重定向,和302含義相同
4XX 客戶端錯誤
400
bad request,請求報⽂存在語法錯誤 ✨
401
unauthorized,表示傳送的請求需要有透過 HTTP 認證的認證資訊 ✨
403 forbidden,表示對請求資源的訪問被伺服器拒絕 ✨ 404 not found,表示在伺服器上沒有找到請求的資源 ✨ 408 Request timeout, 客戶端請求超時
409 Confict, 請求的資源可能引起衝突
5XX 伺服器錯誤
500 internal sever error,表示伺服器端在執⾏請求時發⽣了錯誤 ✨
501 Not Implemented 請求超出伺服器能⼒範圍,例如伺服器不⽀持當前請求所需要的某個功能,或者請求是伺服器不⽀持的某個⽅法
503 service unavailable,表明伺服器暫時處於超負載或正在停機維護,⽆法處理請求505 http version not supported 伺服器不⽀持,或者拒絕⽀持在請求中使⽤的 HTTP 版本
同樣是重定向307,303,302的區別?
302是http1.0的協議狀態碼,在http1.1版本的時候為了細化302狀態碼⼜出來了兩個303和307。
303明確表示客戶端應當採⽤get⽅法獲取資源,他會把POST請求變為GET請求進⾏重定向。 307會遵照瀏覽器標準, 不會從post變為get。
HTTP的keep-alive是⼲什麼的?
在早期的HTTP/1.0中,每次http請求都要建立⼀個連線,⽽建立連線的過程需要消耗資源和時間,為了減少資源消耗, 縮短響應時間,就需要重⽤連線。在後來的HTTP/1.0中以及HTTP/1.1中,引⼊了重⽤連線的機制,就是在http請求頭中加⼊Connection: keep-alive來告訴對⽅這個請求響應完成後不要關閉,下⼀次咱們還⽤這個請求繼續交流。協議規定
HTTP/1.0如果想要保持⻓連線,需要在請求頭中加上Connection: keep-alive。keep-alive的優點:
較少的CPU和記憶體的使⽤(由於同時開啟的連線的減少了) 允許請求和應答的HTTP管線化
降低擁塞控制 (TCP連線減少了)
減少了後續請求的延遲(⽆需再進⾏握⼿) 報告錯誤⽆需關閉TCP連
為什麼有了HTTP為什麼還要HTTPS?
https是安全版的http,因為http協議的資料都是明⽂進⾏傳輸的,所以對於⼀些敏感資訊的傳輸就很不安全,HTTPS就是為了解決HTTP的不安全⽽⽣的。
HTTPS是如何保證安全的?
過程⽐較複雜,我們得先理解兩個概念
對稱加密:即通訊的雙⽅都使⽤同⼀個秘鑰進⾏加解密,⽐如特務接頭的暗號,就屬於對稱加密
對稱加密雖然很簡單效能也好,但是⽆法解決⾸次把秘鑰發給對⽅的問題,很容易被⿊客攔截秘鑰。
⾮對稱加密:
1. 私鑰 + 公鑰= 金鑰對
2. 即⽤私鑰加密的資料,只有對應的公鑰才能解密,⽤公鑰加密的資料,只有對應的私鑰才能解密
3. 因為通訊雙⽅的⼿⾥都有⼀套⾃⼰的金鑰對,通訊之前雙⽅會先把⾃⼰的公鑰都先發給對⽅
4. 然後對⽅再拿著這個公鑰來加密資料響應給對⽅,等到到了對⽅那⾥,對⽅再⽤⾃⼰的私鑰進⾏解密
⾮對稱加密雖然安全性更⾼,但是帶來的問題就是速度很慢,影響效能。解決⽅案:
那麼結合兩種加密⽅式,將對稱加密的金鑰使⽤⾮對稱加密的公鑰進⾏加密,然後傳送出去,接收⽅使⽤私鑰進⾏解密得到對稱加密的金鑰,然後雙⽅可以使⽤對稱加密來進⾏溝通。
此時⼜帶來⼀個問題,中間⼈問題:
如果此時在客戶端和伺服器之間存在⼀箇中間⼈,這個中間⼈只需要把原本雙⽅通訊互發的公鑰,換成⾃⼰的公鑰,這樣中間⼈就可以輕鬆解密通訊雙⽅所傳送的所有資料。
所以這個時候需要⼀個安全的第三⽅頒發證書(CA),證明身份的身份,防⽌被中間⼈攻擊。
證書中包括:簽發者、證書⽤途、使⽤者公鑰、使⽤者私鑰、使⽤者的HASH演算法、證書到期時間等
但是問題來了,如果中間⼈篡改了證書,那麼身份證明是不是就⽆效了?這個證明就⽩買了,這個時候需要⼀個新的技術,數字簽名。
數字簽名就是⽤CA⾃帶的HASH演算法對證書的內容進⾏HASH得到⼀個摘要,再⽤CA的私鑰加密,最終組成數字簽名。
當別⼈把他的證書發過來的時候,我再⽤同樣的Hash演算法,再次⽣成訊息摘要,然後⽤CA的公鑰對數字簽名解密,得到CA 建立的訊息摘要,兩者⼀⽐,就知道中間有沒有被⼈篡改了。
這個時候就能最⼤程度保證通訊的安全了。
HTTP2相對於HTTP1.x有什麼優勢和特點?⼆進位制分幀
幀:HTTP/2 資料通訊的最⼩單位訊息:指 HTTP/2 中邏輯上的 HTTP 訊息。例如請求和響應等,訊息由⼀個或多個幀組成。
流:存在於連線中的⼀個虛擬通道。流可以承載雙向訊息,每個流都有⼀個唯⼀的整數ID HTTP/2 採⽤⼆進位制格式傳輸資料,⽽⾮ HTTP 1.x 的⽂本格式,⼆進位制協議解析起來更⾼效。
頭部壓縮
HTTP/1.x會在請求和響應中中重複地攜帶不常改變的、冗⻓的頭部資料,給⽹絡帶來額外的負擔。
HTTP/2在客戶端和伺服器端使⽤“⾸部表”來跟蹤和儲存之前傳送的鍵-值對,對於相同的資料,不再透過每次請求和響應傳送
⾸部表在HTTP/2的連線存續期內始終存在,由客戶端和伺服器共同漸進地更新; 每個新的⾸部鍵-值對要麼被追加到當前表的末尾,要麼替換表中之前的值。
你可以理解為只發送差異資料,⽽不是全部發送,從⽽減少頭部的資訊量
伺服器推送
服務端可以在傳送⻚⾯HTML時主動推送其它資源,⽽不⽤等到瀏覽器解析到相應位置,發起請求再響應。例如服務端可以主動把JS和CSS⽂件推送給客戶端,⽽不需要客戶端解析HTML時再發送這些請求。
服務端可以主動推送,客戶端也有權利選擇是否接收。如果服務端推送的資源已經被瀏覽器快取過,瀏覽器可以透過傳送RST_STREAM幀來拒收。主動推送也遵守同源策略,伺服器不會隨便推送第三⽅資源給客戶端。
多路復⽤
HTTP 1.x 中,如果想併發多個請求,必須使⽤多個 TCP 連結,且瀏覽器為了控制資源,還會對單個域名有 6-8個的TCP連結請求限制。
HTTP2中:
同域名下所有通訊都在單個連線上完成。 單個連線可以承載任意數量的雙向資料流。
資料流以訊息的形式傳送,⽽訊息⼜由⼀個或多個幀組成,多個幀之間可以亂序傳送,因為根據幀⾸部的流標識可以重新組裝
HTTP的快取的過程是怎樣的?
通常情況下的步驟是:
1. 客戶端向伺服器發出請求,請求資源
2. 伺服器返回資源,並透過響應頭決定快取策略
3. 客戶端根據響應頭的策略決定是否快取資源(這⾥假設是),並將響應頭與資源快取下來
4. 在客戶端再次請求且命中資源的時候,此時客戶端去檢查上次快取的快取策略,根據策略的不同、是否過期等判斷是直接讀取本地快取還是與伺服器協商快取
什麼時候會觸發強快取或者協商快取?強快取
強快取離不開兩個響應頭 Expires 與 Cache-Control
Expires:Expires是http1.0提出的⼀個表示資源過期時間的header,它描述的是⼀個絕對時間,由伺服器返回, Expires 受限於本地時間,如果修改了本地時間,可能會造成快取失效
Expires: Wed, 11 May 2018 07:20:00 GMT
Cache-Control: Cache-Control 出現於 HTTP / 1.1,優先順序⾼於 Expires ,表示的是相對時間
Cache-Control: max-age=315360000
⽬前主流的做法使⽤ Cache-Control 控制快取,除了 max-age 控制過期時間外,還有⼀些不得不提
Cache-Control: public可以被所有⽤戶快取,包括終端和CDN等中間代理伺服器Cache-Control: private只能被終端瀏覽器快取,不允許中繼快取伺服器進⾏快取
Cache-Control: no-cache,先快取本地,但是在命中快取之後必須與伺服器驗證快取的新鮮度才能使⽤Cache-Control: no-store,不會產⽣任何快取
在快取有效期內命中快取,瀏覽器會直接讀取本地的快取資源,當快取過期之後會與伺服器進⾏協商。
協商快取
當第⼀次請求時伺服器返回的響應頭中沒有Cache-Control和Expires或者Cache-Control和Expires過期抑或它的屬性設定為no-cache時,那麼瀏覽器第⼆次請求時就會與伺服器進⾏協商。
如果快取和服務端資源的最新版本是⼀致的,那麼就⽆需再次下載該資源,服務端直接返回304 Not Modified 狀態碼, 如果伺服器發現瀏覽器中的快取已經是舊版本了,那麼伺服器就會把最新資源的完整內容返回給瀏覽器,狀態碼就是 200 Ok。
伺服器判斷快取是否是新鮮的⽅法就是依靠HTTP的另外兩組資訊
Last-Modified/If-Modified-Since
客戶端⾸次請求資源時,伺服器會把資源的最新修改時間 Last-Modified:Thu, 19 Feb 2019 08:20:55 GMT 透過響應部⾸傳送給客戶端,當再次傳送請求是,客戶端將伺服器返回的修改時間放在請求頭 If-Modified-Since:Thu, 19 Feb 2019 08:20:55 GMT 傳送給伺服器,伺服器再跟伺服器上的對應資源進⾏⽐對,如果伺服器的資源更新,那麼返回最新的資源,此時狀態碼200,當伺服器資源跟客戶端的請求的部⾸時間⼀致,證明客戶端的資源是最新的,返回304狀態碼, 表示客戶端直接⽤快取即可。
ETag/If-None-Match
ETag的流程跟Last-Modified是類似的,區別就在於ETag是根據資源內容進⾏hash,⽣成⼀個資訊摘要,只要資源內容有變化,這個摘要就會發⽣鉅變,透過這個摘要資訊⽐對,即可確定客戶端的快取資源是否為最新,這⽐Last-Modified 的精確度要更⾼。
響應頭
因此整體的快取流程圖如下: