HTTP協議基礎進階講解,結合實際應用場景
前言:這篇文章沒有涉及到基礎的協議內容,大部分是開發中會遇到的一些問題。鑑於最近開發遇到一些問題,解決了感到很興奮,也解決了我去年開發中自己遺留下的疑惑。偷得浮生半日閒,我寫這篇文章,目的是為了方便大家理解理論與實際開發中的場景,更快地定位問題,解決開發中遇到的一些問題。
一、什麼是HTTP協議
叫做超文字傳輸協議,他基於TCP/IP協議基礎上做傳輸(知道這個概念就可以)。可以看下我之前在網上看過一張很經典的圖:
可以簡單理解為:在 傳送端 和 接收端 之間的這個超文字解析方式協議就是HTTP協議
為了通俗易懂我這裡把他拆出來,先在linux上面講解。因為不管是瀏覽器還是linux傳輸這個都是依據http協議。
1、首先通過linux的 curl 命令來請求介面:
curl -v https://blog.csdn.net/phoenix/web/v1/comment/template/List
如上圖所示:任何請求都會有我上面表明的這幾個內容。
那麼linux是怎麼知道哪個是響應頭,哪個是響應內容呢,就是根據換行符來決定的。仔細看上面的請求部分、響應頭、響應內容,都有個換行,linux就是根據這個識別的,那麼可以推測瀏覽器也可能是根據這個來識別。當然瀏覽器展示的更直觀。
二、請求中為什麼會遇到跨域請求
首先要明確一點的是,跨域請求實際上是瀏覽器進行攔截的。(瀏覽器的安全策略攔截)你通過linux的curl去請求介面是怎麼也不會遇到跨域。所以跨域實際出現一般都是前後端分離場景。
1、什麼是跨域請求,就是同一資源,請求別的域資源。簡而言之域不同:包括3種情況。
有的人會有疑問是什麼域?看下面截圖,就是瀏覽器url地址和請求的url。只要這兩個地址有以下任何一個不同就會出現跨域
- 協議不同,http協議 和 https協議
- 埠不同,(截圖所示就是埠不同,url上面的預設埠為80,請求地址的為7179,所以這裡跨域了)
- 域名(ip)不同,www.baidu.com 和 www.a.com (包括ip和域名,若一個是ip一個域名也會跨域,即使該域名指向該ip)
三、跨域如何解決
一般常用有兩種種:前端nginx、後端設定cros允許跨域。(完全夠用)
開發中可以在專案中設定proxy代理。通過特定識別符號號,例如 /api 來進行代理。
解決跨域比較簡單,這裡不詳細說明。但是有時候會遇到比較特殊的情況,可以看下這篇文章:
https://blog.csdn.net/weixin_40910372/article/details/100068498
四、為什麼每次會有options請求
options(預檢/嗅探請求)可能會導致請求變慢,每次進行介面請求時候,瀏覽器會先發出一個options請求,然後才發起正式的請求。
那麼為什麼會有options請求呢,導致它的原因是:在cros跨域請求下瀏覽器將請求分為兩種:1、簡單請求,2、非簡單請求(複雜請求),在非簡單請求下,就會有options請求。
簡單請求:(屬於以下幾點的就是簡單請求,其他的都是非簡單請求)
- 請求方式有且只限於:GET、POST、 HEAD
- 請求頭不超出以下欄位(且沒有其他自定義欄位):
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
解決辦法(優化):可以通過設定響應頭部的Access-Control-Max-Age 來設定預檢請求有效期,即在設定的時間內只有第一次會發送出資料,下次這個介面請求(相同介面&相同引數時)不會再發出這個預檢請求,
而是傳送真請求。
方法1、通過nginx新增響應頭
location /test/ { add_header ‘Access-Control-Max-Age’ 600; proxy_pass http://a**********/; }
方法2、後端直接設定這個響應頭並設定時間
注意:在Chrome瀏覽器在debug狀態,或者勾選上Disable cache,這個配置將失效。