前言:這篇文章沒有涉及到基礎的協議內容,大部分是開發中會遇到的一些問題。鑒於最近開發遇到一些問題,解決了感到很興奮,也解決了我去年開發中自己遺留下的疑惑。偷得浮生半日閑,我寫這篇文章,目的是為了方便大家理解理論與實際開發中的場景,更快地定位問題,解決開發中遇到的一些問題。
一、什么是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,這個配置將失效。