HTTP基本知識、跨域和調試技巧

HTTP基礎

其實不少面試問HTTP的3次握手,4次揮手,我以爲價值不大,能夠幫助你理解HTTP的原理,死背硬記的對於你開發沒有做用,而是去理解它就行。
前端只關心URL、headers和data,接下來也圍繞着它們展開。
瞭解HTTP請求能夠看看:https://developer.mozilla.org...html

1.瞭解URL

URL比較簡單,就簡單介紹一下,將URL分爲主要的3部分:前端

  1. router,路由。路由地址可不能錯,這就跟收件地址同樣,填錯收貨的就不是既定的那我的了。
  2. search,查詢字符串,就是?後面的字符串,以鍵值對的形式經過「&」鏈接,例如:「?key1=value1&key2=value2」。查詢字符串就是發送到後臺的數據,跟普通的post請求相比,get請求以明文的形式存儲在訪問歷史,瀏覽器和路由器都很容易查獲得,容易泄露,因此不建議用get請求;其次通常瀏覽器都有限制URL的長度,因此不適合發送大數據量的數據。
  3. hash,哈希值或者稱爲錨,是#後面的字符串,通常做爲單頁應用的路由地址,或者文檔的錨。

clipboard.png

2.前端經常使用的headers

2.1.Content-Type(重要)

告訴客戶端,用什麼形式前端的數據發送到後臺:application/x-www-form-urlencoded、multipart/form-data、text/plain等。ios

2.2 application/x-www-form-urlencoded

最多見的方式以鍵值對的字符串傳輸(相似URL的search),但不能傳輸文件,幾乎全部的ajax框架都是默認以此種方式發送。
發送到後臺的數據見下圖:
clipboard.png面試

2.3 multipart/form-data

這種方式會以鍵值對的形式經過分隔符連接,以字符串給後臺,能夠傳輸文件,也能夠傳輸普通數據。
經常使用場景:ajax

// 源生的form提交可設置enctype="multipart/form-data",通常表單中有文件會自動設爲該值
<form action="post" enctype="multipart/form-data"></form>

// ajax請求,經過formdata對象來達成此目的
const formdata = new new FormData();
formdata.append("key","value")
$.ajax({
...
data: formdata,
processData: false,    // 取消對數據的預處理,由於formdata不須要預處理
headers: {
   "Content-Type": undefined    // 客戶端會自動給它設置正確的值,不要設爲multipart/form-data,這樣設的後果會致使分隔符不正確
},
...
})

若是在抓包確認劃線的一致的話就是正確發送過去了。json

clipboard.png

2.4text/plain

這個不多會用到了,普通文本,能夠是任意數據,除了文件。axios

2.5binary

二進制流,僅限一個文件。後端

3 Data-Type

告訴後臺你但願返回什麼類型的數據,如xml,html,script,json,jsonp,text等,或者你跟後臺約定的也可。可是實際返回的並不是跟預期一致,仍是由後臺決定的。跨域

4 自定義header

若是跟後臺有約定header,如token等,也可傳到後臺。瀏覽器

headers["token"] = "MD5KEY";

CORS跨域

跨域問題的根本問題就是同源策略,旨在防止網站被攻擊,這裏不作贅述。
CORS是後臺的工做,但前端工程師仍是要了解CORS,這樣纔有後臺擡槓的資本。如下是後臺response配置CORS的headers,若是後臺不懂,請讓他了解了解CORS。

Access-Control-Allow-Origin

簡單說,容許跨域訪問的host,必須設置,不然不容許跨域。

// 如需容許全部資源均可以訪問您的資源,您能夠如此設置:這很危險,建議仍是維護白名單。並且‘*’有侷限性
Access-Control-Allow-Origin: *

// 如需容許https://developer.mozilla.org訪問您的資源,您能夠設置:
Access-Control-Allow-Origin: https://developer.mozilla.org, htto://10.10.1.12:8089

Access-Control-Allow-Credentials

若是想跨域傳輸cookies,須要Access-Control-Allow-Credentials與XMLHttpRequest.withCredentials 或Fetch API中的Request() 構造器中的credentials 選項結合使用。Credentials必須在先後端都被配置(即the Access-Control-Allow-Credentials header 和 XHR 或Fetch request中都要配置)才能使帶credentials的CORS請求成功。

// 客戶端,以axios爲例
axios.defaults.withCredentials = true

// 服務端
rsponse.headers[Access-Control-Allow-Credentials] = true

Access-Control-Request-Method

容許跨域的請求的方法。

Access-Control-Allow-Methods: POST, GET, OPTIONS

Access-Control-Allow-Headers

response的header中Access-Control-Allow-Headers 用於 preflight request (即會在實際請求發送以前先發送一個option請求)中,列出了將會在正式請求的 Access-Control-Expose-Headers 字段中出現的首部信息。

簡單首部,如 simple headers、Accept、Accept-Language、Content-Language、Content-Type (只限於解析後的值爲 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三種MIME類型(不包括參數)),它們始終是被支持的,不須要在這個首部特地列出。

preflight request--options請求

不少人在抓包時會很鬱悶怎麼會無故端多出了一個OPTIONS請求,請不要奇怪,這只是CORS策略的預檢請求,就像你要去跟別人借個東西,要先問問對方肯不願同樣。

什麼狀況下會發送OPTIONS請求?

簡單的說,就是有自定義headers,Content-Type的值不屬於下列之一:application/x-www-form-urlencoded,multipart/form-data,text/plain的請求會觸發OPTIONS請求。若是產生OPTIONS請求,須要後臺去響應它,容許它跨域。
https://www.jianshu.com/p/b55... 能夠參考篇文章。

抓包和問題分析

PS: 我主要使用Chrome的DevTools工具

確保發送的數據沒問題

不要相信你的代碼,以抓包工具的爲準!!!!!要相信若是抓包的數據有問題,那麼就是你的代碼有問題。
不要相信你的代碼,以抓包工具的爲準!!!!!要相信若是抓包的數據有問題,那麼就是你的代碼有問題。
不要相信你的代碼,以抓包工具的爲準!!!!!要相信若是抓包的數據有問題,那麼就是你的代碼有問題。

  1. URL確保跟後臺約定的一致
  2. headers要尤爲關注Content-Type(請關注上文的Content-Type),GET請求沒有Content-Type.
  3. 請求的參數是否正確

clipboard.png

後臺返回什麼了?

若是你確認你發送的數據沒問題,那麼該看看後臺響應了什麼,若是響應的數據有問題,那麼是後臺的責任。
若是是跨域的要查看有沒有響應CORS的請求頭。

clipboard.png

clipboard.png

控制檯查看錯誤和警告

若是你的代碼出錯,或者http錯誤,包括CORS錯誤,控制檯會拋出錯誤,錯誤信息能夠幫助你很快定位問題。
這裏不會詳細介紹DevTools,但你要學會使用DevTools,它會大大提升的調試效率。
clipboard.png

HTTP STATUS

相關文章
相關標籤/搜索