目錄
- http協(xié)議是個什么東西
- http的請求類型都有哪些
- 常見的HTTP首部
- HTTP請求體
- HTTP響應(yīng)體
- HTTP常見的響應(yīng)狀態(tài)碼
- HTTP的cookieg管理
HTTP協(xié)議
HTTP是一種通用的網(wǎng)絡(luò)數(shù)據(jù)傳輸格式优炬,它的傳輸內(nèi)容不僅僅局限于HTML文件或者圖片,所有可以用字節(jié)序列表示的數(shù)據(jù)都可以使用HTTP進行傳輸。
HTTP通過TCP/IP進行數(shù)據(jù)傳輸味混,如果忽略底層的TCP協(xié)議的握手和揮手的細節(jié),對于從客戶端到服務(wù)器的每一個請求和請求的響應(yīng)姊舵,在HTTP1.0有下面幾個步驟:
- 默認情況下亩鬼,客戶端在端口80開啟與服務(wù)器的一個TCP連接,當然也可以指定其他的端口村生。
- 客戶端向服務(wù)器發(fā)送消息嘉涌,請求指定路徑上的資源妻熊。一個HTTP請求包括一個首部,可選項包括一個空行和這次請求的數(shù)據(jù)仑最。
- 服務(wù)器向客戶端發(fā)送響應(yīng)扔役。響應(yīng)以響應(yīng)碼開頭,接著是包含元數(shù)據(jù)的首部警医,可選項包括一個空行以及所請求的文檔數(shù)據(jù)或者錯誤信息亿胸。
- 服務(wù)器關(guān)閉TPC連接坯钦。
在HTTP1.1(目前最常用的就是HTTP1.1)以及以后的HTTP版本中,可以通過一個TCP連接連續(xù)發(fā)送多個請求和接收多個響應(yīng)侈玄。
也就是說婉刀,上面的1和4步驟中間的2和3步驟可以反復執(zhí)行多次。另外拗馒,HTTP1.1中路星,請求數(shù)據(jù)和響應(yīng)數(shù)據(jù)可以分塊發(fā)送溯街,提高了擴展性诱桂。
HTTP請求方法
HTTP請求方法 | 描述 | 是否安全 | 是否冪等 |
---|---|---|---|
GET | 通常用于請求服務(wù)器獲取某個資源 | 是 | 是 |
HEAD | 類似于GET,但是響應(yīng)結(jié)果中不包含響應(yīng)體呈昔,只包含協(xié)議信息和首部挥等,通常用于測試資源是否存在或者是否被修改 | 是 | - |
POST | 客戶端向服務(wù)器提交數(shù)據(jù)(支持HTML的表單數(shù)據(jù)),可能會導致新的資源的建立或者已有資源的修改 | 否 | 否 |
PUT | 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容(全部取代) | 否 | 是 |
PATCH | 客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容(部分取代) | 否 | 是 |
TRACE | 回顯客戶端請求服務(wù)器的原始請求報文堤尾,用于"回環(huán)"診斷 | 是 | - |
OPTIONS | 請求服務(wù)器獲取服務(wù)器支持的各種功能肝劲,可以詢問服務(wù)器支持什么類型的HTTP方法,一般用于性能測試 | 是 | - |
DELETE | 請求服務(wù)器刪除指定的資源 | 否 | 否 |
安全 : 意味著使用該種HTTP請求方法不會發(fā)生任何數(shù)據(jù)的修改或者更新動作郭宝,也就是請求多次也不會影響到資源的狀態(tài)辞槐。
冪等 : 意味著使用該HTTP請求方法請求多次HTTP調(diào)用,無論調(diào)用多少次粘室,請求結(jié)果或者資源的狀態(tài)是一樣的榄檬。
HTTP方法的安全性和冪等性是我們在設(shè)計HTTP接口時候需要重點考慮的兩個因素。
上面提到的POST和PUT方法的功能可以理解為相同的衔统,兩者的主要區(qū)別在于POST不是冪等的鹿榜,而PUT是冪等的。
在目前的Web開發(fā)中锦爵,POST方法已經(jīng)被濫用舱殿,一般很少人會使用PUT,除非是推崇RESTFUL風格編程险掀。
PUT方法和PATCH方法的功能類似沪袭,都是用客戶端請求的數(shù)據(jù)去替換掉服務(wù)器中指定文檔中的內(nèi)容,不過PUT方法是全部替換樟氢,而PATCH方法是部分替換枝恋。
常見的HTTP首部
字段 | 首部類型 | 描述 |
---|---|---|
User-Agent | 請求 | 用戶代理,用于告知服務(wù)器當前客戶端使用的是什么瀏覽器 |
Host | 請求 | 用于指定接收該請求的服務(wù)器的主機名和端口號 |
Accept-Charset | 請求 | 告知服務(wù)器客戶端可以接收和處理哪些字符集 |
Accept-Encoding | 請求 | 告知服務(wù)器客戶端可以接收和處理哪些編碼方式 |
Accept-Language | 請求 | 告知服務(wù)器客戶端可以接收和處理哪些語言 |
Accept | 請求 | 告知服務(wù)器客戶端可以接收和處理哪些媒體類型 |
Referer | 請求 | 提供了包含當前請求的URL的文檔的URL |
Cookie | 請求 | 客戶端通過它向服務(wù)器傳送一個或者多個令牌嗡害,原則上Cookie并不是安全的首部呢诬,Cookie的內(nèi)容也會緩存在客戶端。 |
Cache-Control | 請求 | 告知服務(wù)器對當前的請求的響應(yīng)結(jié)果進行緩存相關(guān)操作 |
Content-Type | 通用 | 告知服務(wù)器或者客戶端當前請求或者響應(yīng)結(jié)果的內(nèi)容(媒體)類型 |
Content-Length | 通用 | 告知服務(wù)器或者客戶端當前請求或者響應(yīng)數(shù)據(jù)體的長度 |
Connection | 請求 | 否需要持久連接集绰,如果指定為Keep-Alive揭保,可以提供持久連接 |
Origin | 請求 | 指明當前的請求是一個針對跨域資源共享的請求 |
Access-Control-Allow-Origin | 響應(yīng) | 表示服務(wù)器允許的該跨域資源共享的請求來源 |
Server | 響應(yīng) | 用于告知客戶端服務(wù)器的相關(guān)信息 |
Set-Cookie | 響應(yīng) | Cookie對應(yīng),表示服務(wù)器設(shè)置成功的Cookie |
Content-Encoding | 響應(yīng) | Accept-Encoding對應(yīng),用于服務(wù)器告知客戶端當前響應(yīng)結(jié)果的內(nèi)容編碼 |
Content-Language | 響應(yīng) | 與Accept-Language對應(yīng)鹃骂,用于服務(wù)器告知客戶端當前響應(yīng)結(jié)果的內(nèi)容語言 |
其中 Accept的值可以是以下八種頂級的類型
text/* 表示人可讀的文字台盯。
image/* 表示圖片。
model/* 表示3D模型畏线,如VRML文件静盅。
audio/* 表示音頻。
video/* 表示多媒體圖片寝殴、視頻蒿叠,也可能是音頻。
application/* 表示二進制數(shù)據(jù)蚣常。
message/* 表示協(xié)議特定的信封市咽,如Email消息和HTTP響應(yīng)。
muitipart/* 表示多個文檔和資源的容器抵蚊。
HTTP請求體
如果采用GET請求方法施绎,只需要向遠處服務(wù)器提供URL,URL中的路徑和查詢字符串就可以匹配到需要查詢的資源贞绳。
但是URL中無法提供詳細的客戶端信息谷醉,像POST和PUT這些請求方法所攜帶的數(shù)據(jù)體有可能比較大。
因此HTTP需要請求體冈闭。HTTP請求體包括下面四個部分:
- 一個起始請求行俱尼,包括HTTP方法、路徑拒秘、查詢字符串以及HTTP版本号显。
- HTTP請求的首部。
- 一個空行(兩個連續(xù)的回車或者換行對)躺酒。
- 請求數(shù)據(jù)體押蚤。
GET /wp-admin/admin-ajax.php?postviews_id=23996&action=postviews&_=1538708851063 HTTP/1.1
Host: www.importnew.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Referer: http://www.importnew.com/23996.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
postviews_id=23996&action=postviews&_=1538708851063
HTTP響應(yīng)體
響應(yīng)體和請求體的格式類似,主要是返回服務(wù)器的響應(yīng)數(shù)據(jù)到客戶端羹应,包括服務(wù)器的一些信息和響應(yīng)數(shù)據(jù)體揽碘。HTTP響應(yīng)體主要包括下面的四個部分:
1、一個起始響應(yīng)行园匹,包括HTTP版本雳刺、狀態(tài)碼、狀態(tài)碼描述裸违。
2掖桦、HTTP響應(yīng)的首部。
3供汛、一個空行(兩個連續(xù)的回車或者換行對)枪汪。
4涌穆、響應(yīng)數(shù)據(jù)體。
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 05 Oct 2018 03:07:37 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=2
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.3
X-Robots-Tag: noindex
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip
2995
Keep-Alive
在使用HTTP1.0的時候會為每個請求打開一個新的TCP連接雀久,實際上宿稀,這導致了一個典型Web會話中打開和關(guān)閉所有連接所花費的事件遠遠大于實際傳輸數(shù)據(jù)所消耗的時間,特別是響應(yīng)結(jié)果包含很多小文檔的會話赖捌。對于使用SSL或者TLS加密的HTTPS連接祝沸,這個問題更加嚴重,因為建立一個安全的Socket的握手過程遠比建立常規(guī)的Socket需要更多的工作越庇。
在HTTP1.1和后面的版本中罩锐,服務(wù)器不必在返送響應(yīng)之后就關(guān)閉連接。已經(jīng)建立的連接可以保持打開悦荒,在同一個Socket上等待來自客戶端的新請求唯欣。簡單來說嘹吨,就是可以在一個TCP連接上連續(xù)發(fā)送多個請求和連續(xù)進行多個請求的響應(yīng)搬味。
客戶端可以在HTTP請求首部中添加一個Connection請求頭,指定值為Keep-Alive蟀拷,這樣就能實現(xiàn)Socket的重用:
Connection: Keep-Alive
HTTP1.1或者之后的版本碰纬,Keep-Alive是默認開啟的,不需要顯式指定问芬,如果需要關(guān)閉可以設(shè)置為close:
Connection: close
一旦開啟了Keep-Alive悦析,服務(wù)器在關(guān)閉一個Socket連接之前,如果有新的客戶端再次連接到服務(wù)器此衅,那么就是重用Socket强戴。在JDK中可以通過系統(tǒng)屬性來控制如果使用HTTP的Keep-Alive:
http.keepAlive:默認值為true,默認開啟HTTP的Keep-Alive挡鞍。
http.maxConnections:同時保持打開的Socket數(shù)量的最大值骑歹,默認值為5。
http.keepAlive.remainingData:默認值為false墨微,如果設(shè)置為true道媚,則JDK在丟棄連接之后會完成剩余數(shù)據(jù)的清理。
sun.net.http.errorstream.enableBuffering:默認值為false翘县,如果設(shè)置為true最域,則嘗試緩存400和500狀態(tài)碼的相對小的錯誤流,從而能釋放連接以備后續(xù)使用锈麸。
sun.net.http.errorstream.bufferSize:為緩存錯誤流的緩沖區(qū)的字節(jié)大小镀脂,默認值為4096字節(jié),只有上一項為true的時候才有意義忘伞。
sun.net.http.errorstream.timeout:默認值為300ms薄翅,讀取錯誤流超時的毫秒數(shù)钞馁。
常見的HTTP狀態(tài)碼
簡單的說
- 響應(yīng)碼100-199表示一個提供信息的響應(yīng)。
- 響應(yīng)碼200-299表示請求成功匿刮。
- 響應(yīng)碼300-399表示重定向僧凰。
- 響應(yīng)碼400-499表示一個客戶端引發(fā)的錯誤。
- 響應(yīng)碼500-599表示一個服務(wù)器引發(fā)的錯誤熟丸。
狀態(tài)碼 | 狀態(tài)碼消息 | 含義 | HttpURLConnection中的常量 | 簡單描述 | ||
---|---|---|---|---|---|---|
1xx | - | 信息狀態(tài)碼训措。 | - | 不常見,暫不考慮 | ||
100 | Continue | 服務(wù)器準備接受請求主體光羞,客戶端發(fā)送請求主體绩鸣;這允許客戶端在請求發(fā)送大量數(shù)據(jù)之前詢問服務(wù)器是否接受請求。 | - | 不常見纱兑,暫不考慮 | ||
101 | Switching | Protocols | 服務(wù)器接受客戶端在Upgrade首部字段中要求改變應(yīng)用的協(xié)議請求呀闻,如從HTTP轉(zhuǎn)換為WebSockets。 | - | 不常見潜慎,暫不考慮 | |
2xx | - | 表示請求成功捡多。 | - | - | ||
200 | OK | 最常見的響應(yīng)碼,代表請求成功铐炫。如果請求方法是GET或者POST垒手,所請求的數(shù)據(jù)與正常的首部都包含在響應(yīng)體中。如果請求方法是HEAD倒信,則只包含首部信息科贬。 | HTTP_OK | 處理請求成功 | ||
201 | Created | 服務(wù)器已經(jīng)在響應(yīng)體中指定的URL創(chuàng)建了對應(yīng)的資源”钣疲客戶端現(xiàn)在應(yīng)當嘗試加載該URL榜掌。這個響應(yīng)碼只在響應(yīng)POST請求時發(fā)送。 | HTTP_CREATED | 創(chuàng)建成功 | ||
202 | Accepted | 表示請求已經(jīng)被處理乘综,但是處理尚未結(jié)束憎账,所以不會返回任何響應(yīng)數(shù)據(jù)。 | HTTP_ACCEPTED | 接受請求 | ||
203 | Non-Authoritative | Information | 由緩存代理或者其他本地源返回資源的表示瘾带,不能保證是最新的鼠哥。 | HTTP_NOT_AUTHORITATIVE | 無權(quán)威的返回結(jié)果 | |
204 | No | Content | 服務(wù)器已經(jīng)成功處理了該請求,但是沒有信息發(fā)回給客戶端看政。一般是由于服務(wù)器上的表單處理邏輯的問題朴恳,只接收數(shù)據(jù)不返回數(shù)據(jù)。 | HTTP_NO_CONTENT | 無返回內(nèi)容 | |
205 | Reset | Content | 服務(wù)器已經(jīng)成功處理了該請求允蚣,但是沒有信息發(fā)回給客戶端于颖。客戶端應(yīng)該清除發(fā)送請求的表單信息嚷兔。 | HTTP_RESET | 重置內(nèi)容 | |
206 | Partial | Content | 服務(wù)器返回客戶端請求的資源的部分內(nèi)容森渐,而不是整個文檔做入。 | HTTP_PARTIAL | 部分內(nèi)容 | |
3xx | - | 重定向。 | - | - | ||
300 | Multiple | Choices | 服務(wù)器為所請求的文檔提供一組不同的表示同衣。 | HTTP_MULT_CHOICE | 多重選擇 | |
301 | Moved | Permanently | 資源已經(jīng)移動到一個新的URL竟块。客戶端應(yīng)當自動加載這個URL的資源耐齐。 | HTTP_MOVE_PERM | 永久移動 | |
302 | Moved | Temporarity | 資源暫時移動到一個新的URL浪秘,但其位置在不久的將來還會再次改變。 | HTTP_MOVE_TEMP | 臨時移動 | |
4xx | - | 客戶端錯誤 | - | - | ||
400 | Bad | Request | 客戶端向服務(wù)器發(fā)出的請求使用了不正確的語法埠况。 | HTTP_BAD_REQUEST | 錯誤請求 | |
401 | Unauthorized | 訪問這個URL需要身份驗證耸携,一般是用戶名和口令。 | HTTP_UNAUTHORIZED | 未授權(quán) | ||
403 | Forbidden | 服務(wù)器理解請求辕翰,但是有意拒絕進行處理夺衍。 | HTTP_FORBIDDEN | 禁止訪問 | ||
404 | Not | Found | 最常見的錯誤響應(yīng),指示服務(wù)器找不到所請求的資源喜命。 | HTTP_NOT_FOUND | 未找到資源 | |
405 | Method | Not | Allowed | 請求方法不支持用于請求指定的資源沟沙。 | HTTP_BAD_METHOD | 方法禁用 |
406 | Not | Acceptable | 所請求的資源不能以客戶端希望的格式提供,客戶端期望的格式由請求HTTP首部Accept字段指定渊抄。 | HTTP_NOT_ACCEPTABLE | 不接受 | |
5xx | - | 服務(wù)端錯誤 | - | - | ||
500 | Internale | Server | Error | 服務(wù)器內(nèi)部異常尝胆。 | HTTP_SERVER_ERROR | 服務(wù)器異常 |
501 | Not | Implemented | 服務(wù)器不具備完成請求的功能丧裁。 | HTTP_NOT_IMPLEMENTED | 尚未實現(xiàn) | |
502 | Bad | Gateway | 服務(wù)器作為網(wǎng)關(guān)或代理护桦,從上游服務(wù)器收到無效響應(yīng)。 | HTTP_BAD_GATEWAY | 錯誤網(wǎng)關(guān) | |
503 | Service | Unavailable | 服務(wù)器暫時無法處理請求煎娇,可能是超負荷或者維護等原因二庵。 | HTTP_UNAVAILABLE | 服務(wù)不可用 |
Cookie和Cookie管理
一般在Servlet應(yīng)用中,Cookie是識別當前用戶缓呛,實現(xiàn)持久會話的最佳方式催享。
從過期時間分類來看,Cookie分為會話Cookie和持久Cookie哟绊,會話Cookie的過期時間比較短因妙,持久Cookie的過期時間比較長或者不會過期,Cookie的過期策略等控制應(yīng)該由服務(wù)端控制票髓。
由于Cookie是直接暴露在客戶端攀涵,一般不能使用Cookie存放敏感的數(shù)據(jù),需要存放敏感數(shù)據(jù)可以考慮使用數(shù)據(jù)加密處理洽沟。
很多網(wǎng)站使用一些小文本串在連接之間存儲持久的客戶端狀態(tài)以故,這些小文本串稱為Cookie(中文翻譯為:小甜點)。
Cookie在請求和響應(yīng)的首部從服務(wù)器傳到客戶端裆操,再從客戶端傳回服務(wù)器怒详,服務(wù)器使用Cookie來指示sessionID炉媒、購物車內(nèi)容、登錄憑據(jù)等昆烁。
除了簡單的name=value對吊骤,Cookie可以有多個屬性來控制它們的作用域,包括過期日期、路徑静尼、域水援、端口、版本和安全選項茅郎。
JDK中java.net.CookieStore類提供了對Cookie的增刪查操作蜗元,它的默認實現(xiàn)是java.net.InMemoryCookieStore,如果實現(xiàn)CookieStore系冗,JDK中的Cookie默認是存放在內(nèi)存中的奕扣。
另外,java.net.CookieManager內(nèi)部持有CookiePolicy和CookieStore掌敬,定義了一系列管理Cookie的方法惯豆,一般通過CookieManager操作Cookie,當然也可以通過實現(xiàn)CookieStore奔害,覆蓋默認的CookieManager來實現(xiàn)Cookie的自定義管理楷兽。