HTTP
-
HTTP(Hyper Text Transfer Protocol),譯為超文本傳輸協議
- 是互聯網中應用最廣泛的應用層協議之一
- 設計HTTP最初的目的是:提供一種發布和接收HTML頁面的方法,由URI來標識具體的資源
- 后面用HTTP來傳遞的資料格式不僅僅是HTML,應用非常廣泛
- (為何叫 超文本?因為它傳輸的資料除了文本還有圖片,視頻,音頻啊_)
-
HTML( Hyper Text Markup Language):超文本標記語言
- 用以撰寫網頁
維基百科上的介紹

版本
- 1991年,HTTP/0.9
- 只支持GET請求方法獲取文本資料(比如HTML檔案),且不支持請求頭、回應頭等,無法向服務器傳遞太多資訊
- 1996年,HTTP/1.0
- 支持POST、HEAD等請求方法,支持請求頭、回應頭等,支持更多種資料型別(不再局限于文本資料)
- 瀏覽器的每次請求都需要與服務器建立一個TCP連接,請求處理完成后立即斷開TCP連接
- 1997年,HTTP/1.1(最經典、使用最廣泛的版本,目前很多還是用該版本)
- 支持PUT、DELETE等請求方法
- 采用持久連接(Connection: keep-alive),多個請求可以共用同一個TCP連接
- 2015年,HTTP/2.0 (穩定可升級)
- 2018年,HTTP/3.0 (開發中)
標準
- HTTP的標準
- 由萬維網協會(W3C)、互聯網工程任務組(IETF)協調制定,最終發布了一系列的RFC
- RFC(Request For Comments,可以譯為:請求意見稿)
- HTTP/1.1 最早是在1997年的RFC 2068中記錄的
- 該規范在1999年的RFC 2616中已作廢
- 2014年又由RFC 7230系列的RFC取代
- HTTP/2 標準于2015年5月以RFC 7540正式發表,取代HTTP/1.1成為HTTP的實作標準
- HTTP/1.1 最早是在1997年的RFC 2068中記錄的
- 中國的RFC
- 1996年3月,清華大學提交的適應不同國家和地區中文編碼的漢字統一傳輸標準被IETF通過為RFC 1922
- 成為中國大陸第一個被認可為RFC檔案的提交協議
報文格式

ABNF
- ABNF(Augmented BNF)
- 是BNF(Backus-Naur Form,譯為:巴科斯-瑙爾范式)的修改、增強版
- 在RFC 5234中表明:ABNF用作internet中通信協議的定義語言
- ABNF是最嚴謹的HTTP報文格式描述形式,脫離ABNF談論HTTP報文格式,往往都是片面、不嚴謹的
- 關于HTTP報文格式的定義
- RFC 2616 4.HTTP Message(舊)
- RFC 7230 3.Message Format(新)
ABNF - 核心規則

報文格式 - 整體

報文格式 - request-line、status-line

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

URL的編碼
- URL中一旦出現了一些特殊字符(比如中文、空格),需要進行編碼
- 在瀏覽器地址欄輸入URL時,是采用UTF-8進行編碼
- 比如
- 編碼前:https://www.baidu.com/s?wd=百度
- 編碼后:https://www.baidu.com/s?wd=華為
Xshell + telnet
- 安裝一個Xshell(安全終端模擬軟體),在Xshell中使用telnet
- 可以直接面向HTTP報文與服務器互動
- 可以更清晰、直觀地看到請求報文、回應報文的內容
- 可以檢驗請求報文格式的正確與否

請求方法
-
RFC 7231, section 4: Request methods:描述了8種請求方法
-
GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE
-
RFC 5789, section 2: Patch method:描述了PATCH方法
-
GET:常用于讀取的操作,請求引數直接拼接在URL的后面(瀏覽器對URL是有長度限制的)
-
POST:常用于添加、修改、洗掉的操作,請求引數可以放到請求體中(沒有大小限制)
-
HEAD:請求得到與GET請求相同的回應,但沒有回應體
- 使用場景舉例:在下載一個大檔案前,先獲取其大小,再決定是否要下載,以此可以節約帶寬資源
-
OPTIONS:用于獲取目的資源所支持的通信選項,比如服務器支持的請求方法
- OPTIONS * HTTP/1.1
-
PUT:用于對已存在的資源進行整體覆寫
-
PATCH:用于對資源進行部分修改(資源不存在,會創建新的資源)
-
DELETE:用于洗掉指定的資源
-
TRACE:請求服務器回顯其收到的請求資訊,主要用于HTTP請求的測驗或診斷
-
CONNECT:可以開啟一個客戶端與所請求資源之間的雙向溝通的通道,它可以用來創建隧道(tunnel)
- 可以用來訪問采用了 SSL (HTTPS) 協議的站點
頭部欄位(Header Field)
- 頭部欄位可以分為4種型別
- 請求頭欄位(Request Header Fields)
- 有關要獲取的資源或客戶端本身資訊的訊息頭
- 回應頭欄位(Response Header Fields)
- 有關回應的補充資訊,比如服務器本身(名稱和版本等)的訊息頭
- 物體頭欄位(Entity Header Fields)
- 有關物體主體的更多資訊,比如主體長度(Content-Length)或其MIME型別
- 通用頭欄位(General Header Fields)
- 同時適用于請求和回應訊息,但與訊息主體無關的訊息頭
- 請求頭欄位(Request Header Fields)
請求頭欄位



回應頭欄位



狀態碼(Status Code )
- 在RFC 2616 10.Status Code Definitions規范中定義
- 狀態碼指示HTTP請求是否已成功完成
- 狀態碼可以分為5類
- 資訊回應:100~199
- 成功回應:200~299
- 重定向:300~399
- 客戶端錯誤:400~499
- 服務器錯誤 :500~599
常見狀態碼
-
100 Continue
- 請求的初始部分已經被服務器收到,并且沒有被服務器拒絕,客戶端應該繼續發送剩余的請求,如果請求已經完 成,就忽略這個回應
- 允許客戶端發送帶請求體的請求前,判斷服務器是否愿意接收請求(服務器通過請求頭判斷)
- 在某些情況下,如果服務器在不看請求體就拒絕請求時,客戶端就發送請求體是不恰當的或低效的
-
200 OK:請求成功
-
302 Found:請求的資源被暫時的移動到了由Location頭部指定的URL上
-
304 Not Modified:說明無需再次傳輸請求的內容,也就是說可以使用快取的內容
-
400 Bad Request:由于語法無效,服務器無法理解該請求
-
401 Unauthorized:由于缺乏目標資源要求的身份驗證憑證
-
403 Forbidden:服務器端有能力處理該請求,但是拒絕授權訪問
-
404 Not Found:服務器端無法找到所請求的資源
-
405 Method Not Allowed:服務器禁止了使用當前HTTP方法的請求
-
406 Not Acceptable:服務器端無法提供與Accept-Charset以及Accept-Language指定的值相匹配的回應
-
408 Request Timeout:服務器想要將沒有在使用的連接關閉
- 一些服務器會在空閑連接上發送此資訊,即便是在客戶端沒有發送任何請求的情況下
-
500 Internal Server Error:所請求的服務器遇到意外的情況并阻止其執行請求
-
501 Not Implemented:請求的方法不被服務器支持,因此無法被處理
- 服務器必須支持的方法(即不會回傳這個狀態碼的方法)只有 GET 和 HEAD
-
502 Bad Gateway:作為網關或代理角色的服務器,從上游服務器(如tomcat)中接收到的回應是無效的
-
503 Service Unavailable:服務器尚未處于可以接受請求的狀態
- 通常造成這種情況的原因是由于服務器停機維護或者已超載
Form提交 - 常用屬性
-
action:請求的URI
-
method:請求方法(GET、POST)
-
enctype:POST請求時,請求體的編碼方式
-
application/x-www-form-urlencoded(默認值)
- 用&分隔引數,用=分隔鍵和值,字符用URL編碼方式進行編碼
-
multipart/form-data
- 檔案上傳時必須使用這種編碼方式
-
multipart/form-data
-
參考RFC 1521
-
請求頭
- Content-Type: multipart/form-data; boundary=xxx

說明
-
boundary
- 分界符,用于對引數的分隔
- 引數開頭 --boundary,注意前面必需要有2個 -- 符號
- 最后以 --boundary-- 結束
請求示例

同源策略
- 瀏覽器有 同源策略(Same-Origin Policy)
- 它規定了:默認情況下,AJAX請求只能發送給同源的URL
- 同源是指3個相同:協議、域名(IP)、埠
- 當Ajax請求如果發現不是同源的URL,就會被攔截,這就是所謂的跨域

- img、script、link、iframe、video、audio等標簽不受同源策略的約束
跨域
- 解決Ajax跨域請求的常用方法
- CORS(Cross-Origin Resource Sharing),跨域資源共享
- JSONP(以前比較舊的處理方式)
- 服務端代理
- Nginx代理
CORS
- CORS的實作需要客戶端和服務器同時支持
- 客戶端
- 所有的瀏覽器都支持(IE至少是IE10版本及以上)
- 服務器
- 需要添加回應頭資訊(Access-Conrol-Allow-Origin)
- 告訴瀏覽器,這是一個允許跨域訪問的請求
- 客戶端
JSONP
- 使用 script 標簽加載一個介面地址,介面回傳的是js代碼,并主動呼叫頁面中的指定方法
- 現在基本不使用
服務端代理
- 后端專門寫一個服務接收前端的URL引數,這個請求由后端去請求,得到資料后再回傳給前端,因為后端是不會有跨域的限制
- 后端介面和前端需要在同源URL中
- 使用麻煩,基本不使用
Nginx代理
- 前端請求與Nginx那邊協商好的需要跨域的一個地址,但是是一個同源的URL地址
- Nginx接到這個請求后,將該地址再轉發到原始的需要跨域的地址中
- 和上面的服務端代碼類似,但配置更簡單
- 推薦使用
Cookie
- 用于在客戶端(瀏覽器)存盤資料,小快取
- 容量小
- 服務器和客戶端都可以 設定Cookie資料,都可以去修改
- 客戶端是直接去使用API設定
- 服務端是通過回應頭中的 Set-Cookie 引數設定
- 有效期
- 默認不設定有效期,就是 會話級別的,當瀏覽器一關,就會清空
- 設定了有效期,當有效期一過,也會失效,這種瀏覽器關了是不會清空的
- 獲取范圍
- 同域名IP,不同埠也是可以共享的
- t1.baidu.com 與 t2.baidu.com 默認是不能共享的,因為不是同一個域名
- 如果給 domian 設定為 .baidu.com 就能兩個域名共享cookie了
- 上級目錄設定的cookie,下級目錄可以獲取到,而下級目錄設定的cookie,上級目錄不能獲取
- 如何讓上級獲取到下級目錄設定的cookie呢
- 設定path屬性 document.cookie = "key=value;path=/"
Session
- 會話,用于在服務器存盤與客戶端相關的資料
- 它能識別客戶端的請求來自哪個會話
建立用戶會話

-
當用戶登錄成功后,服務器會生成一個唯一的 ID(SeesionID)作為Key保存在Session中,value就是該用戶資訊相關引數
-
然后回傳回應頭的時候,在 Set-Cookie 中設定 JSEESIONID=XXX
-
這樣就將這個SessionID保存到客戶端了
-
下次客戶端再發起請求的時候,就會將Cookie中的這個 JSEESIONID 一起發給后端
-
后端收到后去 Session 中查詢這個KEY,就能知道這次請求是哪個用戶的了
快取(Cache)
-
Cache的發音和Cash(現金)一樣

-
實際上,HTTP的快取機制遠遠比上圖的流程要復雜
-
通常會快取的情況是:GET請求+靜態資源(比如HTML、CSS、JS、圖片等)
-
Ctrl + F5:可以強制重繪快取
快取 - 回應頭
- Pragma:作用類似于Cache-Control,HTTP/1.0的產物
- Expires:快取的過期時間(GMT格式時間),HTTP/1.0的產物
- 問題:過期時間是和客戶端時間比較的,每個人的電腦時間都有可能不一樣,所以快取不靠譜
- Cache-Control: 設定快取策略
- no-storage: 不快取資料到本地
- public: 允許用戶、代理服務器快取資料到本地
- private: 只允許用戶快取資料到本地
- max-age: 快取的有效時間(多長時間不過期),單位秒
- no-cache: 每次需要發請求給服務器詢問快取是否有變化,再來決定如何使用快取
- 優先級: Pragma > Cache-Control(ETag > Last-Modified) > Expires
快取 - 請求頭
- lf-None-Match
- 如果上一次的回應頭中有ETag,就會將ETag的值作為請求頭的值
- 如果服務器發現資源的最新摘要值跟lf-None-Match不匹配,就會回傳新的資源(200 OK)
- 否則,就不會回傳資源的具體資料(304 Not Modified)
- lf-Modified-Since
- 如果上一次的回應頭中沒有ETag,有Last-Modified,就會將Last-Modified的值作為請求頭的值
- 如果服務器發現資源的最后一次修改時間晚于lf-Modified-Since,就會回傳新的資源(200 OK)
- 否則,就不會回傳資源的具體資料(304 Not Modified)
快取 - Last-Modified vs ETag
- Last-Modified的缺陷
- 只能精確到秒級別,如果資源在1秒內被修改了,客戶端將無法獲取最新的資源資料
- 如果某些資源被修改了(最后一次修改時間發生了變化),但是內容并沒有任何變化
- 會導致相同資料重復傳輸,沒有使用到快取
- ETag可以辦到
- 只要資源的內容沒有變化,就不會重復傳輸資源資料
- 只要資源的內容發生了變化,就會回傳最新的資源資料給客戶端
快取的使用流程圖

代理服務器 (Proxy Server)
- 特點
- 本身不生產內容
- 處于中間位置轉發上下游的請求和回應
- 面向下游的客戶端:它是服務器
- 面向上游的服務器:它是客戶端

正向代理、反向代理
- 正向代理:代理的物件是客戶端
- 如:瀏覽器中的HTTP代理
- 反向代理:代理的物件是服務器
- 如:Nginx代理

正向代理 - 作用
- 隱藏客戶端身份
- 繞過防火墻(突破訪問限制)
- Internet訪問控制
- 資料過濾
- ...

-
一些免費的正向代理
-
https://ip.jiangxianli.com/
-
https://www.kuaidaili.com/free/inha/
-
反向代理 - 作用
- 隱藏服務器身份
- 安全防護
- 負載均衡

抓包工具的原理
- Fiddler、Charles等抓包工具的原理:在客戶端啟動了正向代理服務

- 需要注意的是
- Wireshark的原理是:通過底層驅動,攔截網卡上流過的資料
代理服務器 相關的頭部欄位
- Via:追加經過的每一臺代理服務器的主機名(或域名)
- X-Forwarded-For:追加請求方的IP地址
- X-Real-IP:客戶端的真實IP地址

CDN
- CDN(Content Delivery Network或Content Distribution Network),譯為:內容分發網路
- 利用最靠近每位用戶的服務器 ?更快更可靠地將音樂、圖片、視頻等資源檔案(一般是靜態資源)傳遞給用戶

-
使用前后對比

-
CDN運營商在全國、乃至全球的各個大樞紐城市都建立了機房
- 部署了大量擁有高存盤高帶寬的節點,構建了一個跨運營商、跨地域的專用網路
-
內容所有者向CDN運營商支付費用,CDN將其內容交付給最終用戶
CDN DNS服務器
-
CDN 有自己的DNS服務器,為了更快速的決議IP給用戶
-
正常沒有CDN的請求

- 使用了CDN的請求
- 當瀏覽器向DNS服務器查詢的時候,DNS服務器會將該查詢指向到離你最近的一臺CDN DNS服務器


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294085.html
標籤:其他
上一篇:【docker系列】詳解阿里云服務器安裝docker
下一篇:在開發中將git運用自如
