全網最詳細的HTTP 協議總結!請收藏!

點擊上方 java項目開發選擇 設爲星標javascript

優質項目,及時送達html

-----前端

Http 協議基礎

經典五層模型

應用層——傳輸層——網絡層——數據鏈路層——物理層vue

  1. 物理層主要做用是定義物理設備如何傳輸數據,指代物理硬件java

  2. 數據鏈路層在通訊的實體間創建數據鏈路鏈接,基本計算機二進制傳輸react

  3. 網絡層爲數據在節點之間傳輸建立邏輯鏈路web

  4. 傳輸層爲 TCP 或 UDP,能夠想象爲一條管道spring

  5. 應用層爲 HTTP,能夠想象爲一個包數據庫

基本概念:一個 tcp 能夠發送多個 http 請求,一個 http 請求必須在一個 tcp 鏈接裏json

http 發展歷史

http/0.9

  • 只有一個命令 GET

  • 沒有 HEADER 等描述數據的信息

  • 服務器發送完畢,就關閉 TCP 鏈接

http/1.0

  • 增長了不少命令,POST,PUT

  • 增長了 status code 和 header

  • 多字符集支持、多部分發送、權限、緩存等

http/1.1

  • 支持了持久鏈接

  • pipeline,管道化

  • 增長 host 和其餘一些命令

http2

  • 全部數據以二進制傳輸,擺脫原來的字符串

  • 同一個鏈接裏面發送多個請求再也不須要按照順序來,並行

  • 頭信息壓縮以及推送等提升效率的功能,服務端能夠主動發送信息,提高性能

三次握手

http 不存在鏈接,只有請求和響應TCP 鏈接能夠發送多個 http 請求,TCP 鏈接有三次握手網絡請求的消耗

  1. 客戶端發送鏈接數據包

  2. 服務端開啓 TCP SOCKET,再給客戶端發送數據包

  3. 客戶端拿到數據包,再給服務端發送確認數據包

第三次是爲了不第二次握手丟失,致使服務端一直開啓端口鏈接

URI——URL 和 URN

URI

統一資源標誌符/Uniform Resource Identifier

  • 用來惟一標識互聯網上的信息資源

  • 包括 URL 和 URN

URL

統一資源定位器/Uniform Resource Locator

  • http://user:pass@host.com:80/path?query=string#hash

  • http 協議

  • user:pass 用戶認證,基本用不到

  • host.com 定位服務在互聯網上的位子,能夠爲 IP 或者域名

  • 80 端口,web 服務,物理服務器上多個 web 服務,不帶端口默認訪問 80

  • path 路由,web 服務上具體的內容

  • query 搜索參數,如何進行搜索和查找,傳參

  • hash 錨點定位工具

此類格式的都叫作 URL,好比 http,ftp 協議

URN

永久統一資源定位符

  • 在資源移動以後還能被找到

  • 目前尚未很是成熟的使用方案

http 報文格式

起始行

  • 請求報文:GET /text/test.txt HTTP/1.0

  • 響應報文:HTTP/1.0 200 OK

頭部

  • 請求頭:Accept:text/* Accept-Language:en,fr

  • 響應頭:Content-type:text/plain Content-length:19

主體

  • 請求體:參數

  • 響應體:返回的數據

HTTP 的方法

  • 用來定義對於資源的操做

  • 經常使用有 GET,POST 等

  • 從定義上講有各自的語義

HTTP CODE

  • 定義服務器對請求的處理結果

  • 各個區間的 CODE 有各自的語義

    • 100-199 還須要一些操做才能發送請求

    • 200-299 操做成功

    • 300-399 重定向

    • 400-499 發送的請求有問題 401 認證 403 被拒絕 404 找不到

    • 500-599 服務端問題

  • 好的 HTTP 服務能夠經過 CODE 判斷結果

建立一個簡單的 web 服務

const http = require("http");http .createServer(function(req, res) { console.log("req come", req.url);
res.end("123"); }) .listen(9999);

HTTP 各類特性

CORS 跨域請求的限制與解決

瀏覽器對於非同域的請求會攔截,請求仍是會發送,後臺服務返回內容,可是瀏覽器會攔截掉並報錯

簡單請求

  • 容許方法僅爲 GET,HEAD,POST

  • Content-Type 僅爲 text/plain,multipart/form-data,application/x-www-form-urlencoded

  • 請求頭限制,僅部分固定請求頭容許

  • XMLHttpRequestUpload 對象均沒有註冊任何事件監聽器

  • 請求中沒有使用 ReadableStream 對象

res.writeHead(200, { "Access-Control-Allow-Origin": "*"});

預請求

先經過 OPTION 請求訪問服務端,返回告訴瀏覽器容許接下來發送的 POST 請求,瀏覽器就不會攔截

res.writeHead(200, { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "", //容許的請求頭 "Access-Control-Allow-Methods": "", //容許的請求方法 "Access-Control-Max-Age": "" //預請求不需option驗證的最大時間});

jsonp

<script src="http://127.0.0.1:8888" />

Cache-Control

  • public 任何地方均可以進行緩存

  • private 只有發起請求的瀏覽器進行緩存

  • no-cache 本地能夠存緩存,但須要後臺驗證事後才能使用

  • max-age 秒數,緩存存在的最大時間

  • s-maxage 秒數,在代理服務器,會代替 max-age

  • max-stale 秒數,發起請求主動帶的頭的到期時間

  • must-revalidate 從新驗證

  • proxy-revalidate 用在緩存服務器上,必須從新驗證

  • no-store 不存儲緩存

  • no-transform 用在代理服務器,不改動返回內容

http .createServer(function(req, res) { res.writeHead(200, { "Content-Type": "text/javascript", "Cache-Control": "max-age=20" //會取緩存的內容,請求不會發送到服務器 }); res.end("123"); }) .listen(9999);

通常緩存會是一個比較長的時間,這就致使服務端更新內容,客戶端卻仍是取老的靜態資源。如今經常使用的方法是每次打包時在靜態路徑上添加一個 hash 碼,hash 碼根據文件改變而來,這樣瀏覽器訪問靜態資源時就會重新請求。

緩存驗證 Last-Modified 和 Etag 的使用

有 Cache-Control 的狀況下

驗證頭

Last-Modified上次修改時間,給資源設置上一次什麼時候修改配合 if-Modified-Since 或者 if-Unmodified-Since 使用對比上次修改時間判斷是否須要更新

Etag數據簽名,數據惟一標識,數據修改,那麼簽名會不同配合 if-Match 或者 If-Non-Match 使用對比資源的簽名判斷是否使用緩存

//服務端進行etag的驗證const etag=req.headers['if-none-match']if(etag==='777'){ res.writeHead(304,{ 'Cache-Control':'max-age=200000,no-cache', 'Last-Modified':'123' 'Etag':'777' }) res.end('')}) else { res.writeHead(200,{ 'Cache-Control':'max-age=200000,no-cache', 'Last-Modified':'123' 'Etag':'777' }) res.end('123')}

Cookie 和 Session

Cookie

在服務端返回數據時,經過 Set-Cookie 保存在瀏覽器,瀏覽器下次在同域的請求中會在頭帶上 Cookie,

  • 經過 Set-Cookie 設置

  • 下次請求會自動帶上

  • 鍵值對,能夠設置多個

  • max-age 和 expires 設置過時時間

  • Secure 只在 https 的時候發送

  • HttpOnly 沒法經過 document.cookie 訪問

const host = req.headers.hostconst html=fs.readFileSync('test.html'.'utf8')if (host === "test.com") { res.writeHead(200, { "Set-Cookie": ["id=123;max-age=2", "abc=456;HttpOnly;domain=test.com"] //此時test.com下的全部二級域名均可以訪問到cookie })}res.end('html')

Session

常常作法是將保存在 session 中的用戶惟一 ID 存入 Cookie,下次請求時拿到 Cookie,經過 Cookie 在 Session 拿到用戶信息,進行操做。

Http 長鏈接

http1.1 默認是長鏈接, 是在 tcp 上順序發送請求,瀏覽器 tcp 併發限制爲 6,就是同時能夠存在 6 個鏈接。因此瀏覽器加載首頁時,先建立 6 個 TCP 鏈接,而後 http 是在這六個鏈接中順序發送的。

數據協商

客戶端在發送請求時,限定須要拿到的數據格式,內容等。服務端根據這些限制來操做,服務端不必定按照規定返回。請求

  • Accept 想要的數據類型

  • Accept-Encoding 數據編碼方式進行傳輸,限制服務器對數據的壓縮方式

  • Accept-Language 但願展現的語言

  • User-Agent 瀏覽器的相關信息返回

  • Content-Type 實際返回的數據格式

  • Content-Encoding 對應 Accept-Encoding,聲明傳輸方式

  • Content-Language 返回的語言

重定向

經過 URL 訪問資源時,服務器告訴瀏覽器資源換位子了,並告訴新的位置,瀏覽器再請求新的位置,301 永久變動,302 暫時變動,301 的返回會在緩存中提取

if (req.url === "/old") { res.writeHead(302, { Location: "/new" }); res.end("");}if (req.url === "/new") { res.writeHead(200, {}); res.end("1234");}

Content-Security-Policy

內容安全策略

  • 限制資源獲取

  • 報告資源獲取越權

  • default-src 限制全局

  • 指定資源類型

res.writeHead(200, { //僅容許http和https "Content-Security-Policy": "default-src http:https:", //僅容許本站腳本 "Content-Security-Policy": "default-src 'self'", //限制特定類型 "Content-Security-Policy": "script-src http:https:" //彙報 "Content-Security-Policy": "script-src ; report-uri /report"})res.end("123")
- END -

推薦案例

溫暖提示

爲了方便你們更好的學習,本公衆號常常分享一些完整的單個功能案例代碼給你們去練習, 若是本公衆號沒有你要學習的功能案例,你能夠聯繫小編(微信:xxf960513)提供你的小需求給我,我安排咱們這邊的開發團隊免費幫你完成你的案例。
注意:只能提單個功能的需求不能要求功能太多,好比要求用什麼技術,有幾個頁面,頁面要求怎麼樣?


請長按識別二維碼

想學習更多的java功能案例請關注

Java項目開發

若是你以爲這個案例以及咱們的分享思路不錯,對你有幫助,請分享給身邊更多須要學習的朋友。別忘了《留言+點在看》給做者一個鼓勵哦!

本文分享自微信公衆號 - web項目開發(javawebkaifa)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索