最近在研究京東的微前端框架@micro-zoe/micro-app
按照文檔配好主應(yīng)用和微應(yīng)用以后,將微應(yīng)用打包編譯拣帽,使用http-server --cors
啟動(dòng)后疼电,在主應(yīng)用中訪問時(shí),調(diào)某個(gè)接口報(bào)錯(cuò)了:
上圖是一個(gè)動(dòng)態(tài)國際化資源的請(qǐng)求减拭,顯示跨域了 這就很奇怪了蔽豺,其他靜態(tài)資源能正常拉取,證明子應(yīng)用是支持跨域訪問的拧粪,但是這個(gè)請(qǐng)求掛掉了
這個(gè)報(bào)錯(cuò)也很離譜:
Cross-Origin Resource Sharing error: HeaderDisallowedByPreflightResponse
從報(bào)錯(cuò)看應(yīng)該還是跨域的問題修陡,我就猜測(cè)是 http-server
這個(gè)工具本身的問題
進(jìn)行了大量的搜索,在他的github上找到一個(gè)issue:[Question] How to set cors headers?
這里面的一個(gè)回答引起了我的注意??
這里說
--cors=xxx
就可以在 allow header 上加一個(gè) xxx可霎,
所以我試著將我的子應(yīng)用啟動(dòng)命令改了一下:
- http-server --cors
+ http-server --cors='*'
然后再訪問魄鸦,居然就好了??
太離譜了。癣朗。拾因。
雖然解決了問題,但心里面還是一堆疑惑旷余,
比如绢记,上面那個(gè)報(bào)錯(cuò)里面的 preflight
是個(gè)啥?
為了搞清這個(gè)報(bào)錯(cuò)正卧,查了很多資料蠢熄,下面記錄一下我學(xué)到的一些東西
預(yù)檢請(qǐng)求preflight
Preflight請(qǐng)求是一種用于CORS(跨域資源共享)的HTTP請(qǐng)求,它通常在實(shí)際請(qǐng)求(比如GET穗酥、POST护赊、PUT等)之前發(fā)送,以確定實(shí)際請(qǐng)求是否安全砾跃。當(dāng)瀏覽器需要跨域發(fā)送一個(gè)請(qǐng)求時(shí)骏啰,會(huì)先發(fā)送一個(gè)OPTIONS請(qǐng)求,該請(qǐng)求包含了一些頭部信息抽高,如Origin判耕、Access-Control-Request-Method和Access-Control-Request-Headers等。服務(wù)器收到這個(gè)請(qǐng)求后翘骂,會(huì)根據(jù)請(qǐng)求頭中的信息來判斷實(shí)際請(qǐng)求是否安全壁熄。如果服務(wù)器認(rèn)為實(shí)際請(qǐng)求是安全的,就會(huì)返回一個(gè)包含Access-Control-Allow-Origin碳竟、Access-Control-Allow-Methods和Access-Control-Allow-Headers等頭部信息的響應(yīng)草丧,以允許瀏覽器發(fā)送實(shí)際請(qǐng)求。
Preflight請(qǐng)求的目的是確庇ㄎΓ跨域請(qǐng)求的安全性昌执,防止惡意攻擊和信息泄露。在實(shí)際應(yīng)用中,Preflight請(qǐng)求往往是由瀏覽器自動(dòng)發(fā)起的懂拾,開發(fā)者可以通過設(shè)置服務(wù)器的CORS響應(yīng)頭來控制Preflight請(qǐng)求的行為煤禽。
下面這篇文章更加詳細(xì)的舉例介紹了預(yù)檢請(qǐng)求: 淺談瀏覽器中的preflight請(qǐng)求 寫得很好??
總結(jié)一下就是:
- 預(yù)檢請(qǐng)求是瀏覽器自發(fā)的行為
通常preflight請(qǐng)求不需要用戶自己去管理和干預(yù),它的發(fā)出的響應(yīng)都是由瀏覽器和服務(wù)器自動(dòng)管理的
- 預(yù)檢請(qǐng)求只會(huì)在存在跨域的時(shí)候觸發(fā)
所以我單獨(dú)訪問子應(yīng)用時(shí)并沒有發(fā)現(xiàn)這種情況岖赋。檬果。。
- 預(yù)檢請(qǐng)求會(huì)在實(shí)際請(qǐng)求之前發(fā)送
可以看到我的報(bào)錯(cuò)截圖的確是這樣的
存在一個(gè) 204 的 preflight
什么時(shí)候會(huì)觸發(fā)預(yù)檢請(qǐng)求呢唐断?
使用
GET
POST
HEAD
以外的請(qǐng)求方法時(shí)請(qǐng)求頭中存在
Accept
Accept-Language
Content-Language
Content-Type
DPR
Downlink
Save-Data
Viewport-Width
Width
以外的字段時(shí)
(這也是我的微應(yīng)用工程中的請(qǐng)求觸發(fā)preflight的原因选脊。工程里面有個(gè)攔截器,給每個(gè)請(qǐng)求都加了個(gè)自
定義的請(qǐng)求頭栗涂。知牌。。)
-
Content-Type 中存在
text/plain
multipart/form-data
application/x-www-form-urlencoded
以外的字段時(shí) -
XMLHttpRequestUpload
對(duì)象注冊(cè)了事件監(jiān)聽器時(shí) - 使用了
ReadableStream
對(duì)象
以上條件只要滿足了一個(gè)斤程,就會(huì)觸發(fā)預(yù)檢請(qǐng)求