相信大家在開發過程中經常會用到 Ajax發起請求,其中,最常見的就是post和get請求,當然也有一些不常用的,比如head、put、delete、options等。今天開發時遇到這樣一個問題,困擾了我大半天最後簡直吐血:
先是控制台那邊報錯:403 forbidden,并且提示:Invalid CORS request
仔細一看發現——請求方法竟然是OPTIONS:

image.png
這就有點意思了,因為我代碼寫的明明是axios.post()!
在網上查了半天,最後終于弄明白了原因,原來對于一些post方法,浏覽器必須先發送一個“預檢請求”來确認伺服器是否允許該請求,允許的話再發送真正的請求。
并且發送的請求内容類型如果不是 application/x-www-form-urlencoded,multipart/form-data 或 text/plain 這三者的話,便會觸發options請求。
看了看我自己的代碼:
axios({
method: 'post',
url,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
},
data: JSON.stringify(param)
})
Content-Type明顯是不符合上述三種情況的,為此艱辛的嘗試了網上各種辦法。
首先是最簡單的:直接修改Content-Type——
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
然而不行。
接着嘗試了網上的第二種辦法:使用 URLSearchParams轉換資料格式——
var params = new URLSearchParams()
params.append('param1', 'value1')
params.append('param2', 'value2')
很可惜,也無效。
最後我甚至加載了新的包,用來攔截請求的發起,把請求資料轉化為可用模式之後再發起請求——
首先安裝qs
npm install --save qs
然後對axios進行配置,就是在封裝axios的地方添加以下代碼:
import qs from 'qs'
// 添加響應攔截器
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,這次我仍然失敗了。

image.png
至此我已經瀕臨崩潰,然而——你以為我會放棄嗎!不!我一定要解決這個問題,我繼續查資料,查啊查查啊查,終于發現可以通過後端配置解決這個問題。
首先我的控制台報錯為:

image.png
這意味着:
伺服器端背景接口沒有允許OPTIONS請求,導緻無法找到對應接口位址
背景方法允許OPTIONS請求,但是一些配置檔案中(如安全配置),阻止了OPTIONS請求
背景允許OPTIONS請求,并且接口也允許OPTIONS請求,但是頭部比對時出現不比對現象
那麼我就需要後端同僚——
後端允許options請求
關閉對應的安全配置
增加對應的頭部支援
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");
當然,這就是後端的任務了,更加詳細具體的請大家移步這裡——
等後端同僚改了配置之後問題成功解決,我也如釋重負,雖然修改bug時最終具體操作的并不是我們前端人員,但我還是記錄下了這個過程,希望大家遇到類似問題的時候,能夠用最快最簡單的方式解決這個問題,減少試錯的體驗。