最近開發(fā)過程中,為了避免跨域,于是在服務(wù)端添加了Access-Control-Allow-Origin,前端出現(xiàn)一個小異常,每次請求次數(shù)都是2次,第一次請求的methods為options,第二次才是正式的請求。每個接口請求2次很浪費(fèi)資源,百度了下,這個請求叫做預(yù)請求,現(xiàn)在就來學(xué)習(xí)下。
一、什么是預(yù)請求?
跨域請求資源時瀏覽器為確認(rèn)請求來源的安全性,會在正式的請求之前做一次預(yù)校驗請求,待服務(wù)器允許之后才能發(fā)送正式的請求,這個預(yù)校驗請求就是options請求。
并不是每次跨域資源請求都會發(fā)送options請求,當(dāng)跨域請求為簡單請求的時就不會發(fā)送預(yù)校驗請求,當(dāng)跨域請求為復(fù)雜請求時才會發(fā)送預(yù)校驗請求。
什么是簡單請求?
- 請求方式只能是:
GET、POST、HEAD。 -
HTTP請求頭限制這幾種字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID。 -
Content-type只能?。?code>application/x-www-form-urlencoded、multipart/form-data、text/plain。
如果不滿足以上條件的就是非簡單請求。
二、如何避免預(yù)請求?
預(yù)請求是瀏覽器的一種安全策略,但是它的存在給會占用瀏覽器的資源,影響頁面的性能,所以要盡可能的減少options請求。而方法也很簡單,使用簡單請求即可:
注意以下幾點(diǎn):
- 而在日常開發(fā)中,比如
Axios里面默認(rèn)的content-type為application/json,這就需要將content-type修改成application/x-www-form-urlencoded即可。 - 如果是
post請求的話,需要對參數(shù)做個處理,需要引用qs庫,將qs.stringify將參數(shù)序列化進(jìn)行傳參。
如果以上沒問題,但是還是有預(yù)請求的話,需要查看header里是否設(shè)置了其他參數(shù),因為在項目開發(fā)中經(jīng)常會將token放到header里進(jìn)行傳參,這種場景需要后端使用Access-Control-Max-Age。
Access-Control-Max-Age的作用
用來指定本次預(yù)檢請求的有效期,單位為秒,這樣只有在第一次請求的時候會有options ,之后瀏覽器會從緩存里讀取響應(yīng),也就不會再發(fā)送options請求。
Access-Control-Max-Age為0表示每次異步請求都發(fā)起預(yù)檢請求,也就是說,發(fā)送兩次請求。
Access-Control-Max-Age為1800表示隔30分鐘才發(fā)起預(yù)檢請求。