HTTP基本知識(shí)、跨域和調(diào)試技巧
HTTP基礎(chǔ)
其實(shí)很多面試問(wèn)HTTP的3次握手,4次揮手,我覺(jué)得價(jià)值不大,可以幫助你理解HTTP的原理,死背硬記的對(duì)于你開發(fā)沒(méi)有作用,而是去理解它就行。
前端只關(guān)心URL、headers和data,接下來(lái)也圍繞著它們展開。
了解HTTP請(qǐng)求可以看看:https://developer.mozilla.org...
1.了解URL
URL比較簡(jiǎn)單,就簡(jiǎn)單介紹一下,將URL分為主要的3部分:
1. router,路由。路由地址可不能錯(cuò),這就跟收件地址一樣,填錯(cuò)收貨的就不是既定的那個(gè)人了。
2. search,查詢字符串,就是?后面的字符串,以鍵值對(duì)的形式通過(guò)“&”連接,例如:“?key1=value1&key2=value2”。查詢字符串就是發(fā)送到后臺(tái)的數(shù)據(jù),跟普通的post請(qǐng)求相比,get請(qǐng)求以明文的形式存儲(chǔ)在訪問(wèn)歷史,瀏覽器和路由器都很容易查得到,容易泄露,所以不建議用get請(qǐng)求;其次一般瀏覽器都有限制URL的長(zhǎng)度,所以不適合發(fā)送大數(shù)據(jù)量的數(shù)據(jù)。
3. hash,哈希值或者稱為錨,是#后面的字符串,一般作為單頁(yè)應(yīng)用的路由地址,或者文檔的錨。
2.前端常用的headers
2.1.Content-Type(重要)
告訴客戶端,用什么形式前端的數(shù)據(jù)發(fā)送到后臺(tái):application/x-www-form-urlencoded、multipart/form-data、text/plain等。
2.2 application/x-www-form-urlencoded
最常見的方式以鍵值對(duì)的字符串傳輸(類似URL的search),但不能傳輸文件,幾乎所有的ajax框架都是默認(rèn)以此種方式發(fā)送。
發(fā)送到后臺(tái)的數(shù)據(jù)見下圖:
2.3 multipart/form-data
這種方式會(huì)以鍵值對(duì)的形式通過(guò)分隔符鏈接,以字符串給后臺(tái),可以傳輸文件,也可以傳輸普通數(shù)據(jù)。
常用場(chǎng)景:
- // 源生的form提交可設(shè)置enctype="multipart/form-data",一般表單中有文件會(huì)自動(dòng)設(shè)為該值
- <form action="post" enctype="multipart/form-data"></form>
- // ajax請(qǐng)求,通過(guò)formdata對(duì)象來(lái)達(dá)成此目的
- const formdata = new new FormData();
- formdata.append("key","value")
- $.ajax({
- ...
- data: formdata,
- processData: false, // 取消對(duì)數(shù)據(jù)的預(yù)處理,因?yàn)閒ormdata不需要預(yù)處理
- headers: {
- "Content-Type": undefined // 客戶端會(huì)自動(dòng)給它設(shè)置正確的值,不要設(shè)為multipart/form-data,這樣設(shè)的后果會(huì)導(dǎo)致分隔符不正確
- },
- ...
- })
如果在抓包確認(rèn)劃線的一致的話就是正確發(fā)送過(guò)去了。
2.4text/plain
這個(gè)很少會(huì)用到了,普通文本,可以是任意數(shù)據(jù),除了文件。
2.5binary
二進(jìn)制流,僅限一個(gè)文件。
3 Data-Type
告訴后臺(tái)你希望返回什么類型的數(shù)據(jù),如xml,html,script,json,jsonp,text等,或者你跟后臺(tái)約定的也可。但是實(shí)際返回的并非跟預(yù)期一致,還是由后臺(tái)決定的。
4 自定義header
如果跟后臺(tái)有約定header,如token等,也可傳到后臺(tái)。
- headers["token"] = "MD5KEY";
CORS跨域
跨域問(wèn)題的根本問(wèn)題就是同源策略,旨在防止網(wǎng)站被攻擊,這里不做贅述。
CORS是后臺(tái)的工作,但前端工程師還是要了解CORS,這樣才有后臺(tái)抬杠的資本。以下是后臺(tái)response配置CORS的headers,如果后臺(tái)不懂,請(qǐng)讓他了解了解CORS。
Access-Control-Allow-Origin
簡(jiǎn)單說(shuō),允許跨域訪問(wèn)的host,必須設(shè)置,否則不允許跨域。
- // 如需允許所有資源都可以訪問(wèn)您的資源,您可以如此設(shè)置:
- Access-Control-Allow-Origin: *
- // 如需允許https://developer.mozilla.org訪問(wèn)您的資源,您可以設(shè)置:
- Access-Control-Allow-Origin: https://developer.mozilla.org
Access-Control-Allow-Credentials
如果想跨域傳輸cookies,需要Access-Control-Allow-Credentials與XMLHttpRequest.withCredentials 或Fetch API中的Request() 構(gòu)造器中的credentials 選項(xiàng)結(jié)合使用。Credentials必須在前后端都被配置(即the Access-Control-Allow-Credentials header 和 XHR 或Fetch request中都要配置)才能使帶credentials的CORS請(qǐng)求成功。
Access-Control-Request-Method
允許跨域的請(qǐng)求的方法。
- Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers
response的header中Access-Control-Allow-Headers 用于 preflight request (即會(huì)在實(shí)際請(qǐng)求發(fā)送之前先發(fā)送一個(gè)option請(qǐng)求)中,列出了將會(huì)在正式請(qǐng)求的 Access-Control-Expose-Headers 字段中出現(xiàn)的首部信息。
簡(jiǎn)單首部,如 simple headers、Accept、Accept-Language、Content-Language、Content-Type (只限于解析后的值為 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三種MIME類型(不包括參數(shù))),它們始終是被支持的,不需要在這個(gè)首部特意列出。
preflight request--options請(qǐng)求
很多人在抓包時(shí)會(huì)很郁悶怎么會(huì)無(wú)端端多出了一個(gè)OPTIONS請(qǐng)求,請(qǐng)不要奇怪,這只是CORS策略的預(yù)檢請(qǐng)求,就像你要去跟別人借個(gè)東西,要先問(wèn)問(wèn)對(duì)方肯不肯一樣。
什么情況下會(huì)發(fā)送OPTIONS請(qǐng)求?
簡(jiǎn)單的說(shuō),就是有自定義headers,Content-Type的值不屬于下列之一:application/x-www-form-urlencoded,multipart/form-data,text/plain的請(qǐng)求會(huì)觸發(fā)OPTIONS請(qǐng)求。如果產(chǎn)生OPTIONS請(qǐng)求,需要后臺(tái)去響應(yīng)它,允許它跨域。
https://www.jianshu.com/p/b55... 可以參考篇文章。
抓包和問(wèn)題分析
PS: 我主要使用Chrome的DevTools工具
確保發(fā)送的數(shù)據(jù)沒(méi)問(wèn)題
不要相信你的代碼,以抓包工具的為準(zhǔn)?。。。?!要相信如果抓包的數(shù)據(jù)有問(wèn)題,那么就是你的代碼有問(wèn)題。
不要相信你的代碼,以抓包工具的為準(zhǔn)?。。。?!要相信如果抓包的數(shù)據(jù)有問(wèn)題,那么就是你的代碼有問(wèn)題。
不要相信你的代碼,以抓包工具的為準(zhǔn)?。。。?!要相信如果抓包的數(shù)據(jù)有問(wèn)題,那么就是你的代碼有問(wèn)題。
- URL確保跟后臺(tái)約定的一致
- headers要尤其關(guān)注Content-Type(請(qǐng)關(guān)注上文的Content-Type),GET請(qǐng)求沒(méi)有Content-Type.
- 請(qǐng)求的參數(shù)是否正確
后臺(tái)返回什么了?
如果你確認(rèn)你發(fā)送的數(shù)據(jù)沒(méi)問(wèn)題,那么該看看后臺(tái)響應(yīng)了什么,如果響應(yīng)的數(shù)據(jù)有問(wèn)題,那么是后臺(tái)的責(zé)任。
如果是跨域的要查看有沒(méi)有響應(yīng)CORS的請(qǐng)求頭。