Http 協(xié)議詳解

簡介

TCP/IP協(xié)議棧

Http 超文本協(xié)議

  1. HTTP 超文本傳輸協(xié)議,是一個無狀態(tài)、TCP/IP的應(yīng)用層協(xié)議,用于定義web瀏覽器與web服務(wù)器之間交換數(shù)據(jù)的過程。
  2. 版本:HTTP/1.0、HTTP/1.1。區(qū)別是1.1版本,客戶端與服務(wù)器連接后,在一個連接上可以獲取多個web資源。
  3. 在TCP/IP協(xié)議棧中的位置:Http(SSL) -> TCP -> IP -> 數(shù)據(jù)鏈路層(從上往下)

Http 請求

組成

  1. 客戶端連上服務(wù)器后,向服務(wù)器請求某個web資源,稱之為客戶端向服務(wù)器發(fā)送一個HTTP請求。
  2. 一個完整的HTTP請求包括如下內(nèi)容:一個請求行,若干消息頭(請求頭)、實體內(nèi)容。

請求行(General)

  1. 客戶端的請求方式:Get/Post
  2. 請求的地址
  3. HTTP版本號:HTTP/1.1
# 火狐查看得出: 
請求網(wǎng)址:https://www.baidu.com/
請求方法:GET
遠(yuǎn)程地址:180.97.33.108:443
狀態(tài)碼:200 OK
版本:HTTP/1.1

# Chrome 查看得出
Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 180.97.33.107:443
Referrer Policy: no-referrer-when-downgrade

請求頭(Request Header):客戶請求主機(jī) 和 客戶端環(huán)境信息

  1. Accept: 指定客戶端接受哪些類型的信息。/:支持任何類型
  2. Accept-Charset:指定客戶端接受的字符集。如,Accept-Charset:iso-8859-1,gb2312
  3. Accept-Encoding:指定客戶端可接受的數(shù)據(jù)壓縮格式
  4. Accept-Language:客戶端的語言環(huán)境
  5. Host:指定被請求資源的Internet主機(jī)和端口號,它通常從HTTP URL中提取出來的
  6. If-Modified-Since:客戶端告訴服務(wù)器資源的緩存時間
  7. Referer:客戶端從哪個資源訪問的服務(wù)端(防盜鏈)
  8. User-Agent:客戶端的軟件環(huán)境(什么操作系統(tǒng),什么瀏覽器)
  9. Cookie:Cookie數(shù)據(jù)
  10. Connection:這個請求完了是保持鏈接還是斷開鏈接(長短鏈接)。close/keep-alive
# 火狐查看得出:
Accept: text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Cache-Control: max-age=0
Connection: keep-alive
Cookie: BAIDUID=750D9FB78B62071D74F66B…1458_21098_26432;
Host: www.baidu.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/60.0


# Chrome 查看得出
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7
Cache-Control: max-age=0
Connection: keep-alive
Cookie: BIDUPSID=0C0589E7DDB5029A8E71E88AFB719857; 
Host: www.baidu.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36

實體內(nèi)容 (Query String Parameters)

  1. 一般是請求的內(nèi)容,如訪問 https://www.baidu.com/?query=entity
# 火狐查看得出:參數(shù)欄
query: entity

# Chrome 查看得出: Query String Parameters
query: entity

Http 響應(yīng)

組成

  1. 一個HTPP響應(yīng)代表服務(wù)器向客戶端回送的數(shù)據(jù)。
  2. Http 響應(yīng)包括:一個狀態(tài)行,若干響應(yīng)頭(消息頭),以及實體內(nèi)容

狀態(tài)行

  1. 服務(wù)器處理的結(jié)果,主要是狀態(tài)碼數(shù)據(jù)
  2. 格式:HTTP版本號/狀態(tài)碼 原因敘述<CRLF>,如 HTTP/1.1 200 OK
  3. 狀態(tài)碼
狀態(tài)碼 含義
100 ~ 199 表示成功接收請求,要求客戶端繼續(xù)提交下一次請求才能完成整個處理過程
200 ~ 299 表示成功接收請求,已經(jīng)完成整個過程。如200
300 ~ 399 為完成請求,客戶端需要進(jìn)一步細(xì)化請求。例如,請求的資源已經(jīng)移動到一個新的地址。常用 302、307、304
400 ~ 499 客戶端的請求有錯誤。常用404
500 ~ 599 服務(wù)器端出現(xiàn)錯誤。常用500
  1. 常用狀態(tài)碼
301、302:資源已經(jīng)不存在了,需要重定向到新地址(控制重定向)
304、307:指定客戶端去拿緩存
401、403:沒有權(quán)限訪問,如用戶名密碼錯誤
404、407:請求的資源沒有,如URL地址錯誤
405:訪問方式錯誤。如Get、Post方式錯誤
500:服務(wù)器端出現(xiàn)問題

響應(yīng)頭 (Response Headers)

  1. Location:配合301、302狀態(tài)碼使用,實現(xiàn)重定向。
response.setStates("301");//設(shè)置狀態(tài)碼為301  
response.setHeader("Location","http://www.baidu.com")// 新網(wǎng)址 
  1. server:服務(wù)器類型
  2. Content-Encoding:壓縮類型;實現(xiàn)壓縮返回
//實現(xiàn)壓縮  
String tDate = "準(zhǔn)備被壓縮的數(shù)據(jù)";  
System.out.println("壓縮前的數(shù)據(jù)大?。? "+tDate.getBytes().length);  
  
ByteArrayOutputStream bout = new ByteArrayOutputStream();  
GZIPOutputStream gout = new GZIPOutputStream(bout);  
gout.write(tDate.getBytes());  
gout.flush();  
gout.close();//寫到字節(jié)數(shù)組流中  
  
byte[] gzip = bout.toByteArray();//得到壓縮后的數(shù)據(jù)  
System.out.println("壓縮后的數(shù)據(jù)大小:  "+gzip.length);  
  
// 通知瀏覽器數(shù)據(jù)采用壓縮格式  
response.setHeader("Content-Encoding", "gzip");//壓縮格式  
response.setHeader("Content-Length",gzip.length+"" );//壓縮數(shù)據(jù)的長度  
response.getOutputStream().write(gzip); 
  1. Content-Length:返回內(nèi)容的長度
  2. Content-Language:返回內(nèi)容的語言
  3. Content-type:返回數(shù)據(jù)的類型
//輸出圖片,可以去tomcat的web.xml中查找  
        response.setContentType("image/bmp; charset=utf-8");  
response.setHeader("Content-Type", "image/bmp");  
InputStream in = this.getServletContext().getResourceAsStream("/");  
int len = 0;  
byte[] buffer = new byte[1024];  
OutputStream out = response.getOutputStream();  
while((len=in.read(buffer))>0){  
    out.write(buffer, 0, len);  
}  
  1. Refresh:瀏覽器多長時間重新刷新一次。也可以實現(xiàn)重定向。
response.setHeader("Refresh","1000");//刷新  
response.setHeader("Refresh","1000; url=http://www.baidu.com");//刷新  
response.setHeader("Refresh","0; url=http://www.baidu.com");//重定向 
  1. Transfer-Encoding:數(shù)據(jù)的傳送格式。chunked-為以塊狀形式傳送。
Transfer-Encoding   chunked 
  1. Last-Modified:告訴瀏覽器當(dāng)前資源的緩存時間。
  2. ETag:緩存相關(guān)的頭,可以實現(xiàn)實時更新,比其他緩存頭(以秒為單位)更及時精確。
  3. Expires:告訴瀏覽器把回送的資源緩存多長時間。-1或0,則不緩存。
//設(shè)置緩存 一定要是當(dāng)前時間 + 控制的緩存時間  
response.setDateHeader("Expires", System.currentTimeMillis() + 1000*3600); 
  1. progma:"no-cache" | Cache-Control:"no-cache" :控制瀏覽器不要緩存。
//不需要緩存       
response.setHeader("Pragma", "no-cache");  
response.setHeader("Cache-Control", "no-cache");  
response.setHeader("Cache-Control", "no-store");  
response.setDateHeader("Expires", 0);//時間頭  
  1. content-disposition:服務(wù)器返回內(nèi)容為需要下載訪問
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("文件名稱", "UTF-8"));
# 火狐查看得出:
Bdpagetype  1
Bdqid   0xf60525b4000463c7
Cache-Control   private
Connection  Keep-Alive
Content-Encoding    gzip
Content-Type    text/html
Cxy_all baidu+a3c955f7fdab4bd322ed0b4a7b8ca3f4
Date    Thu, 21 Jun 2018 11:51:06 GMT
Expires Thu, 21 Jun 2018 11:51:06 GMT
Server  BWS/1.1
Set-Cookie  BDSVRTM=18; path=/
Set-Cookie  BD_HOME=0; path=/
Set-Cookie  H_PS_PSSID=1458_21098_26432; path=/; domain=.baidu.com
Strict-Transport-Security   max-age=172800
Transfer-Encoding   chunked
Vary    Accept-Encoding
X-Ua-Compatible IE=Edge,chrome=1

# Chrome 查看得出: 
Bdpagetype: 2
Bdqid: 0xf24f13cb0003dde3
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Thu, 21 Jun 2018 11:51:58 GMT
Expires: Thu, 21 Jun 2018 11:51:58 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=132; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=26524_1459_21117_18560_26350_20927; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Transfer-Encoding: chunked
X-Ua-Compatible: IE=Edge,chrome=1

實體內(nèi)容(Response Body)

  1. 服務(wù)端返回的內(nèi)容: 訪問 https://www.baidu.com/?query=entity

# 火狐查看得出:響應(yīng)欄 
HTML 的網(wǎng)頁信息

# Chrome 查看得出: 
HTML 的網(wǎng)頁信息

Range,實現(xiàn)斷點下載

請求頭

  1. 告訴服務(wù)器只傳輸一部分web資源,這個頭可以用來實現(xiàn)斷點續(xù)傳功能。
  2. Range:可以通過三種格式設(shè)置要傳輸?shù)淖止?jié)范圍:
  • Range:bytes = 1000-2000 :傳輸范圍從1000 到 2000 字節(jié)。
  • Range:bytes = 1000- :傳輸web資源中第1000個字節(jié)以后的所有內(nèi)容。
  • Range:bytes = 1000 :傳輸最后1000 個字節(jié)。
  1. 代碼:請求中,實現(xiàn)斷電下載
# 請求中,實現(xiàn)斷電下載  
URL url = new URL("http://localhost:8080/javaweb/");//請求的地址  
HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
conn.setRequestProperty("Range", "byte=5-");//請求5字節(jié)以后的數(shù)據(jù),斷點下載  
  
InputStream  in = conn.getInputStream();  
int len = 0;  
byte[] buffer = new byte[1024];  
FileOutputStream out = new FileOutputStream("c:\\a.text",true);//存放的地方  
  
while((len=in.read(buffer))>0){  
    out.write(buffer, 0, len);  
}  
  
in.close();  
out.close();  

響應(yīng)頭字段

  1. Accept-Range:這個字段說明web服務(wù)器是否支持Range
  • Accept-Range:bytes:支持
  • Accept-Range:none:如果不支持
  1. Content-Range:指定了返回web 資源的字節(jié)范圍。這個字段值的格式是:
Content-Range: 1000-3000/5000 # 整個資源是5000,返回的是1000-3000  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容