相信大家在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)用到 Ajax發(fā)起請(qǐng)求,其中,最常見(jiàn)的就是post和get請(qǐng)求,當(dāng)然也有一些不常用的,比如head、put、delete、options等。今天開(kāi)發(fā)時(shí)遇到這樣一個(gè)問(wèn)題,困擾了我大半天最后簡(jiǎn)直吐血:
先是控制臺(tái)那邊報(bào)錯(cuò):403 forbidden,并且提示:Invalid CORS request
仔細(xì)一看發(fā)現(xiàn)——請(qǐng)求方法竟然是OPTIONS:

這就有點(diǎn)意思了,因?yàn)槲掖a寫(xiě)的明明是axios.post()!
在網(wǎng)上查了半天,最后終于弄明白了原因,原來(lái)對(duì)于一些post方法,瀏覽器必須先發(fā)送一個(gè)“預(yù)檢請(qǐng)求”來(lái)確認(rèn)服務(wù)器是否允許該請(qǐng)求,允許的話再發(fā)送真正的請(qǐng)求。
并且發(fā)送的請(qǐng)求內(nèi)容類(lèi)型如果不是 application/x-www-form-urlencoded,multipart/form-data 或 text/plain 這三者的話,便會(huì)觸發(fā)options請(qǐng)求。
看了看我自己的代碼:
axios({
method: 'post',
url,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
data: JSON.stringify(param)
})
Content-Type明顯是不符合上述三種情況的,為此艱辛的嘗試了網(wǎng)上各種辦法。
- 首先是最簡(jiǎn)單的:直接修改Content-Type——
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
然而不行。
- 接著嘗試了網(wǎng)上的第二種辦法:使用 URLSearchParams轉(zhuǎn)換數(shù)據(jù)格式——
var params = new URLSearchParams()
params.append('param1', 'value1')
params.append('param2', 'value2')
很可惜,也無(wú)效。
- 最后我甚至加載了新的包,用來(lái)攔截請(qǐng)求的發(fā)起,把請(qǐng)求數(shù)據(jù)轉(zhuǎn)化為可用模式之后再發(fā)起請(qǐng)求——
首先安裝qs
npm install --save qs
然后對(duì)axios進(jìn)行配置,就是在封裝axios的地方添加以下代碼:
import qs from 'qs'
// 添加響應(yīng)攔截器
axios.interceptors.request.use(
config => {
if (config.method === 'post') {
config.data = qs.stringify(config.data)
}
return config
},
error => {
Promise.reject(error)
}
)
然而我還是too young too naive,這次我仍然失敗了。

至此我已經(jīng)瀕臨崩潰,然而——你以為我會(huì)放棄嗎!不!我一定要解決這個(gè)問(wèn)題,我繼續(xù)查資料,查啊查查啊查,終于發(fā)現(xiàn)可以通過(guò)后端配置解決這個(gè)問(wèn)題。
首先我的控制臺(tái)報(bào)錯(cuò)為:

這意味著:
- 服務(wù)器端后臺(tái)接口沒(méi)有允許OPTIONS請(qǐng)求,導(dǎo)致無(wú)法找到對(duì)應(yīng)接口地址
- 后臺(tái)方法允許OPTIONS請(qǐng)求,但是一些配置文件中(如安全配置),阻止了OPTIONS請(qǐng)求
- 后臺(tái)允許OPTIONS請(qǐng)求,并且接口也允許OPTIONS請(qǐng)求,但是頭部匹配時(shí)出現(xiàn)不匹配現(xiàn)象
那么我就需要后端同事——
- 后端允許options請(qǐng)求
- 關(guān)閉對(duì)應(yīng)的安全配置
- 增加對(duì)應(yīng)的頭部支持
servletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with,Content-Type");
servletResponse.setHeader("Access-Control-Allow-Origin", servletRequest.getHeader("origin"));
servletResponse.setHeader("Access-Control-Allow-Methods", "POST,GET");
當(dāng)然,這就是后端的任務(wù)了,更加詳細(xì)具體的請(qǐng)大家移步這里——
跨域資源共享 CORS 詳解
ajax跨域,這應(yīng)該是最全的解決方案了
等后端同事改了配置之后問(wèn)題成功解決,我也如釋重負(fù),雖然修改bug時(shí)最終具體操作的并不是我們前端人員,但我還是記錄下了這個(gè)過(guò)程,希望大家遇到類(lèi)似問(wèn)題的時(shí)候,能夠用最快最簡(jiǎn)單的方式解決這個(gè)問(wèn)題,減少試錯(cuò)的體驗(yàn)。
作者:huyix
鏈接:http://www.itdecent.cn/p/de3ae95917b1
來(lái)源:簡(jiǎn)書(shū)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。