bug記錄——POST請(qǐng)求變成OPTIONS

相信大家在開(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:

image

這就有點(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,這次我仍然失敗了。

image

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

首先我的控制臺(tái)報(bào)錯(cuò)為:

image

這意味著:

  1. 服務(wù)器端后臺(tái)接口沒(méi)有允許OPTIONS請(qǐng)求,導(dǎo)致無(wú)法找到對(duì)應(yīng)接口地址
  2. 后臺(tái)方法允許OPTIONS請(qǐng)求,但是一些配置文件中(如安全配置),阻止了OPTIONS請(qǐng)求
  3. 后臺(tái)允許OPTIONS請(qǐng)求,并且接口也允許OPTIONS請(qǐng)求,但是頭部匹配時(shí)出現(xiàn)不匹配現(xiàn)象

那么我就需要后端同事——

  1. 后端允許options請(qǐng)求
  2. 關(guān)閉對(duì)應(yīng)的安全配置
  3. 增加對(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)注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容