網(wǎng)絡(luò)協(xié)議(十四)-應(yīng)用層(HTTP)

HTTP
  • HTTP(Hyper Text Transfer Protocol), 譯為超文本傳輸協(xié)議
    -- 是互聯(lián)網(wǎng)中應(yīng)用最廣泛的應(yīng)用層協(xié)議之一
    -- 設(shè)計HTTP最初的目的是: 提供一種發(fā)布和接收HTML頁面的方法, 由URI來標(biāo)識具體的資源
    -- 后面用HTTP來傳遞的數(shù)據(jù)格式不僅僅是HTML, 應(yīng)用非常廣泛

  • HTML(Hyper Text Markup Language): 超文本標(biāo)記語言
    -- 用以編寫網(wǎng)頁

版本
  • 1991年, HTTP/0.9
    -- 只支持GET請求方法獲取文本數(shù)據(jù)(比如HTML文檔), 且不支持請求頭, 響應(yīng)頭等, 無法向服務(wù)器傳遞太多信息

  • 1996年, HTTP/1.0
    -- 支持POST, HEAD等請求方法, 支持請求頭, 響應(yīng)頭等, 支持更多種數(shù)據(jù)類型 (不再局限于文本數(shù)據(jù))
    -- 瀏覽器的每次請求都需要與服務(wù)器建立一個TCP連接, 請求處理完成后立即斷開TCP連接

  • 1997年, HTTP/1.1(最經(jīng)典, 使用最廣泛的版本)
    -- 支持PUT, DELETE等請求辦法
    -- 采用持久連接(Connection: keep-alive), 多個請求可以共用一個TCP連接

  • 2015年, HTTP/2.0

  • 2018年, HTTP/3.0

報文格式
image.png
image.png
  • ABNF (Augmented BNF)
    -- 是BNF (Backus-Naur Form, 譯為: 巴科斯-瑙爾范式)的修改, 增強版
    -- 在RFC 52234中表明: ABNF用作internet中通信協(xié)議的定義語言
    -- ABNF是最嚴謹?shù)?code>HTTP報文格式描述形式, 脫離ABNF談?wù)?code>HTTP報文格式, 往往都是片面, 不嚴謹?shù)?/p>

  • 關(guān)于HTTP報文格式的定義
    -- RFC 2616 4.HTTP Message(舊)
    -- RFC 7230 3.Message Format(新)

image.png
ABNF-核心規(guī)則
image.png
報文格式-request-line, status-line

request-line = method SP request-target SP HTTP-version CRLF
HTTP-version = HTTP-name "/" DIGIT"."DIGIT"
HTTP-name = %48.54.54.50;HTTP

GET /hello/ HTTP/1.1

status-line = HTTP-version SP status-code SP reason-phrase CRLF
status-code = 3DIGIT
reason-phrase = *(HTAB / SP / VCHAR / obs-text)

HTTP/1.1 200
HTTP/1.1 200 OK

報文格式 - header-filed, message-body

header-filed = filed-name ":" OWS field-value OWS
field-name = token
field-value = *(field-content / obs-fold)
OWS = *(SP / HTAB)

message-body = *OCTET

URL的編碼
  • URL中一旦出現(xiàn)了一些特殊字符(比如中文, 空格), 需要進行編碼
    -- 在瀏覽器地址欄輸入URL時, 是采用UTF-8進行編碼

  • 比如
    -- 編碼前: https://www.baidu.com/s?wd=百度
    -- 編碼前: https://www.baidu.com/s?wd=%E5%8D%8E%E4%B8%BA

請求方法
  • GET 常用于讀取的操作, 請求參數(shù)直接拼接在URL的后面(瀏覽器對URL是有長度限制的)

  • POST 常用于添加, 修改, 刪除的操作, 請求參數(shù)可以放到請求體中(沒有大小限制)**(URL也可以拼接參數(shù), 請求體里也拼接參數(shù))**

  • HEAD 請求得到的與GET請求相同的響應(yīng), 但沒有響應(yīng)體
    -- 使用場景舉例: 在下載一個大文件前, 先獲取其大小, 再決定是否要下載. 以此可以節(jié)約帶寬資源

  • OPTIONS 用于獲取目的資源所支持的通信選項, 比如服務(wù)器支持的請求方法
    -- OPTIONS * HTTP/1.1

  • PUT 用于對已存在的資源進行整體覆蓋

  • PATCH 用于對資源進行部分修改(資源不存在, 會創(chuàng)建新的資源)

  • DELETE 用于刪除指定的資源

  • TRACE 請求服務(wù)器回顯其收到的請求信息, 主要用于HTTP請求的測試和診斷

  • CONNECT 可以開啟一個客戶端與所請求資源之間的雙向溝通的通道, 它可以用來創(chuàng)建隧道(tunnel)
    -- 可以用來訪問采用了SSL(HTTPS)協(xié)議的站點

頭部字段(Header Field)
  • 頭部字段可以分為4種類型
    -- 請求頭字段(Request Header Fields)
    ?有關(guān)要獲取的資源或客戶端本身信息的消息頭

-- 響應(yīng)頭字段(ResponseHeader Fields)
?有關(guān)響應(yīng)的補充信息, 比如服務(wù)器本身(名稱和版本等)的消息頭

-- 實體頭字段(Entity Header Fields)
?有關(guān)實體主體的更多信息, 比如主體長度(Content-Length)MIME類型

-- 請求頭字段(General Header Fields)
?同時適用于請求和響應(yīng)消息, 但與消息主體無關(guān)的消息頭

請求頭字段
image.png
image.png
image.png
響應(yīng)頭字段
image.png
image.png
image.png
狀態(tài)碼(Status Code)
  • RFC 2616 10.Status Code Definitions規(guī)范中定義
    -- 狀態(tài)碼指示HTTP請求是否已成功完成

  • 狀態(tài)碼可以分為5
    -- 信息響應(yīng): 100~199
    -- 成功響應(yīng): 200~299
    -- 重定向: 300~399
    -- 客戶端錯誤: 400~499
    -- 服務(wù)器錯誤: 500~599

  • 100 Continue
    -- 請求的初始部分已經(jīng)被服務(wù)器收到, 并且并沒有被服務(wù)器拒絕. 客戶端應(yīng)該繼續(xù)發(fā)送剩余的請求, 如果請求已經(jīng)完成, 就忽略這個響應(yīng)
    -- 允許客戶端發(fā)送帶請求體的請求前, 判斷服務(wù)器是否愿意接手請求(服務(wù)器通過請求頭判斷)
    -- 在某些情況下, 如果服務(wù)器在不看請求體就拒絕請求時, 客戶端就發(fā)送請求體是不恰當(dāng)或者低效的

  • 200 OK 請求成功

  • 302 Found 請求的資源被暫時移動到了由Location頭部指定的URL

  • 304 Not Modified 說明無需再次傳輸請求內(nèi)容, 也就是說可以使用緩存內(nèi)容

  • 400 Bad Request 由于語法無效, 服務(wù)器無法理解該需求

  • 401 Unauthorized 由于缺乏目標(biāo)資源要求的身份驗證憑證

  • 403 Forbidden 服務(wù)器端有能力處理該請求, 但是拒絕授權(quán)訪問

  • 404 Not Found 服務(wù)器端無法找到所請求的資源

  • 405 Method Not Allowed 服務(wù)器禁止了使用當(dāng)前HTTP方法的請求

  • 406 Not Acceptable 服務(wù)器端無法提供與Accept-Charset以及Accept-Language指定的值相匹配的響應(yīng)

  • 408 Request Timeout 服務(wù)器想要將沒有在使用的連接關(guān)閉
    -- 一些服務(wù)器會在空閑連接上發(fā)送此信息, 即便是在客戶端沒有發(fā)送任何請求的情況下

  • 500 Internal Server Error 所請求的服務(wù)器遇到意外的情況并阻止其執(zhí)行請求

  • 501 Not Implemented 請求的方法不被服務(wù)器支持, 因此無法被處理(注意和405的區(qū)別)
    -- 服務(wù)器必須支持的方法(即不會返回這個狀態(tài)碼的方法)只有GETHEAD

  • 502 Bad Gateway 作為網(wǎng)關(guān)或代理角色的服務(wù)器, 從上游服務(wù)器(如tomcat)中接收到的響應(yīng)是無效的

  • 503 Service Unavailable 服務(wù)器尚未處于可以接受請求的狀態(tài)
    -- 通常造成這種情況的原因是由于服務(wù)器停機維護或者已超載

form提交-常用屬性
  • action 請求的URI
  • method 請求方法(GET, POST)
  • enctype POST請求時, 請求體的編碼方式
    -- application/x-www-form-urlencoded(默認值)
    ?用&分隔參數(shù), 用=分隔鍵和值, 字符用URL編碼方式進行編碼

-- multipart/form-data
?文件上傳時必須使用這種編碼方式

form提交-multipart/form-data
  • 參考RFC 1521
  • 請求頭
    -- Content-Type: multipart/form-data; boundary=xxx
    image.png
同源策略
  • 瀏覽器有個同源策略(Same-Origin Policy)
    -- 它規(guī)定了: 默認情況下, AJAX請求只能發(fā)送給同源的URL
    -- 同源是指3個相同: 協(xié)議, 域名(IP), 端口

    image.png

  • img, script, link, iframe, video, audio等標(biāo)簽不受同源策略的約束

跨域資源共享
  • 解決AJAX跨域請求的常用方法
    -- CORS(Cross-Origin Resource Sharing) 跨域資源共享

  • CORS的實現(xiàn)需要客戶端和服務(wù)器同時支持
    -- 客戶端
    ?所有的瀏覽器都支持(IE至少是IE10 版本)

-- 服務(wù)器
?需要返回相應(yīng)的響應(yīng)頭(比如Access-Control-Allow-Origin)
?告知瀏覽器這是一個允許跨域訪問的請求

后端在返回數(shù)據(jù)前就應(yīng)該先判斷origin和允許訪問的是否一致, 否則就算瀏覽器報錯跨域問題, 前端一樣可以拿到數(shù)據(jù), 后端的數(shù)據(jù)就存在不安全性

會話跟蹤
  • HTTP是一種"無狀態(tài)"(stateless)的協(xié)議
    -- 每次客戶端訪問網(wǎng)頁時, 客戶端都會打開與Web服務(wù)器的單獨連接
    -- 并且服務(wù)器不會自動保留之前客戶端請求的任何記錄
    -- 所以服務(wù)器無法識別多個請求是否來自同一個客戶端(比如瀏覽器)

  • 在很多應(yīng)用場景中, 都有以下需求
    -- 服務(wù)器能夠識別出多個請求是夠來自同一個客戶端
    -- 在來自同一個客戶端的多個請求之間共享數(shù)據(jù)

  • 以上需求可以使用會話跟蹤技術(shù)來完成. 在Java中, 實現(xiàn)會話跟蹤的常用方法是
    -- Cookie
    -- Session

Cookie & Session
  • Cookie是直接存儲在瀏覽器本地的一小串?dāng)?shù)據(jù)
    -- 使用document.cookie訪問Cookie
    -- 在修改Cookie時, 只會修改其中提到的Cookie
    -- name=value必須被編碼(encodeURIComponent)
    -- 一個Cookie最大為4kb, 每個網(wǎng)站最多有20+個左右的Cookie(具體取決于瀏覽器)

  • WindowsChrome瀏覽器的Cookie存放位置
    -- C:\Users\用戶名\AppData\Local\Google\Chrome\User Data\Default\Cookies
    -- 使用SQLite數(shù)據(jù)庫進行存儲

Cookie的有效期
  • 如果沒有設(shè)置Cookie的過期時間, 則當(dāng)瀏覽器關(guān)閉時, Cookie就失效了

  • expries
    -- 必須完全采用GMT時區(qū)的格式, 可以受用date.toUTCString來獲取
    -- 例如: expires=Tue, 19 Jan 2038 03:14:07 GMT

  • max-age
    -- 過期時間距離當(dāng)前時間的秒數(shù)
    -- 例如: max-age=60

  • Cookie(只歸一個瀏覽器管)
    -- 在客戶端(瀏覽器)存儲一些數(shù)據(jù), 存儲到本地磁盤(硬盤)
    -- 服務(wù)器可以返回Cookie交給客戶端去存儲

  • Session(針對用戶瀏覽器的, 會話跟蹤)
    -- 在服務(wù)器存儲一些數(shù)據(jù), 存儲到內(nèi)存中

Cookie的作用域
  • domainpath標(biāo)識定義了Cookie的作用域, 即Cookie應(yīng)該發(fā)送給哪些URL

  • domain
    -- 標(biāo)識指定了哪些主機可以接受Cookie
    -- 如果不指定, 默認為當(dāng)前文檔的主機(不包含子域名); 如果指定了domain, 則一般包含子域名
    -- 例如: 如果設(shè)置domain=520it.com, 則Cookie也包含在子域名中(如bbs.520it.com)

  • path
    -- 標(biāo)識指定了主機下的哪些路徑可以接受Cookie, 子路徑也會被匹配
    -- 例如:設(shè)置path=/docs, 則以下地址都會匹配
    ??/docs
    ??/docs/one/
    ??/docs/one/img

服務(wù)器設(shè)置Cookie
  • Cookie通常是由Web服務(wù)器使用響應(yīng)頭Set-Cookie設(shè)置的

  • 關(guān)于max-age

  • -在JavaScript中, 如果設(shè)置為0或者負數(shù), 會立即刪除Cookie
    -- 在Java中: 如果設(shè)置為0, 是立即刪除Cookie; 如果設(shè)置為負數(shù), 按默認情況處理

getSession內(nèi)部的原理
  • 檢查客戶端是否有發(fā)送一個叫做JSESSIONIDCookie
    -- 如果沒有
    ??創(chuàng)建一個新的Session對象, 并且這個Session對象會有一個id
    ??這個Session對象會保留在服務(wù)器的內(nèi)存中
    ??在響應(yīng)的時候, 會添加一個Cookie(JSESSIONID=Session對象的id)給客戶端

-- 如果有
??返回idJSESSIONIDSession對象

JSESSIONID
  • 默認情況下, 當(dāng)用戶關(guān)閉瀏覽器時, Cookie中存儲的JSESSIONID就會被銷毀

  • 可以通過以下代碼延長JSESSIONID在客戶端的壽命

Cookie cookie = new Cookie("JSESSIONID", request.getSession().getId());
cookie.setMaxAge(3600);
response.addCookie(cookie);
Session的有效期
  • Session的有效期默認是30分鐘
  • 可以在web.xml中配置失效時間(單位是分鐘)
<session-config>
    <session-timeout>30</session-timeout>
 </session-config>
總結(jié)
  • Cookie
    -- 數(shù)據(jù)存儲在瀏覽器客戶端
    -- 數(shù)據(jù)有大小和數(shù)量的限制
    -- 適合存儲一些小型, 不敏感的數(shù)據(jù)
    -- 默認情況下, 關(guān)閉瀏覽器后就會銷毀

  • Session
    -- 數(shù)據(jù)存儲在服務(wù)器端
    -- 數(shù)據(jù)沒有大小和數(shù)量的限制
    -- 可以存儲大型, 敏感的數(shù)據(jù)(比如用戶信息)
    -- 默認情況下, 未使用30分鐘后就會銷毀

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市升熊,隨后出現(xiàn)的幾起案子洋访,更是在濱河造成了極大的恐慌旺隙,老刑警劉巖甩恼,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件护戳,死亡現(xiàn)場離奇詭異代嗤,居然都是意外死亡簸州,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門柿估,熙熙樓的掌柜王于貴愁眉苦臉地迎上來循未,“玉大人,你說我怎么就攤上這事秫舌〉难” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵足陨,是天一觀的道長嫂粟。 經(jīng)常有香客問我,道長墨缘,這世上最難降的妖魔是什么星虹? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任零抬,我火速辦了婚禮,結(jié)果婚禮上宽涌,老公的妹妹穿的比我還像新娘平夜。我一直安慰自己,他們只是感情好卸亮,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布忽妒。 她就那樣靜靜地躺著,像睡著了一般兼贸。 火紅的嫁衣襯著肌膚如雪段直。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天溶诞,我揣著相機與錄音坷牛,去河邊找鬼。 笑死很澄,一個胖子當(dāng)著我的面吹牛京闰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播甩苛,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蹂楣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了讯蒲?” 一聲冷哼從身側(cè)響起痊土,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎墨林,沒想到半個月后赁酝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡旭等,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年酌呆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搔耕。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡隙袁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弃榨,到底是詐尸還是另有隱情菩收,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布鲸睛,位于F島的核電站娜饵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏官辈。R本人自食惡果不足惜箱舞,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一遍坟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧褐缠,春花似錦政鼠、人聲如沸风瘦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽万搔。三九已至胡桨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瞬雹,已是汗流浹背昧谊。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留酗捌,地道東北人呢诬。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像胖缤,于是被迫代替她去往敵國和親尚镰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容