近期項目中遇到一個bug,其中解決過程比較有意思,特此記錄下來。有一天看到報警記錄有一個500服務端的錯誤,量不多,一週都不必定有一個,先根據服務器裏的本地日誌拿到了當時請求的相關信息像UA、cookie什麼的,肯定了請求是來自iPhone上的qq瀏覽器,由於咱們業務在手機瀏覽器裏沒有入口,因此這種狀況不多。因而找來iPhone下載QQ瀏覽器嘗試復現問題。ios
描述:iPhone中某些版本的QQ瀏覽器中提交訂單時,報錯提示服務端異常,經抓包排查發現提交訂單時post請求的body爲空,content-length爲0,因而開始了此次艱難蛋疼的bugfix過程。瀏覽器
其中手機是iPhone 8p,QQ瀏覽器版本9.1.0.4110,ios版本11.0,請求UA是Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0 MQQBrowser/9.1.0 Mobile/15B87 Safari/604.1 MttCustomUA/2 QBWebViewType/1 WKType/1。(雖然這些對此次後期排查修復都沒什麼蛋用,但有時仍是頗有用的)。服務器
我的喜歡debug時用排除法,先肯定問題所在cookie
首先排查發post請求過程有沒有問題,由於有可能依賴的某個包在國產QQ瀏覽器上有兼容性問題,但一路排查發起過程都沒什麼問題,最後不用依賴包,直接用XMLHttpRequest手寫了個post請求依然很差使,排除了發請求的依賴包的問題。數據結構
排查項目是否對發請求有影響,有些內部的監控上報的包可能會對XMLHttpRequest中方法作改寫,因而一路刪除懷疑的依賴包,最後單純返回了一個簡單頁面,頁面內發一個post請求,body依然爲空,至此排除了全部依賴包的影響(這個過程很費時間,這個思路不是很好)。frontend
排查到這就有點蛋疼了,Google搜了下看有沒有人和我遇到一樣的問題,發現qq瀏覽器論壇上17年就有人提出這個問題了,類似的帖子大概有七八個,但有官方迴應的也就一兩個,回覆也只是說讓升級瀏覽器。。。用戶升級瀏覽器還行,開發者得解決問題啊,排查到這已經肯定了一點,就是qq瀏覽器確定對post請求的支持是有問題的。post
意識到qq瀏覽器有問題,下意識想針對qq瀏覽器作下兼容處理。開始想post改爲get請求,可是post中的body不是簡單地數據結構,若是是如下數據改爲get還好,如:測試
body
{
name: 'frontend',
age: '8',
}
複製代碼
可是遇到較爲複雜的數據結構就很差使了,如:spa
{
times: [123,234,2423,12],
favour: {
detail: 'sdadfa',
}
}
複製代碼
由於改爲get後是經過query來傳遞數據的,query是隻支持字符串的;另外這種方式隱隱約約感受會坑很大,因此排除了這種方式。因而嘗試另外一種方式,把body數據放到header裏面,反正HTTP協議裏對header大小是沒作限制的,因此這樣乾的debug
const xhr = new XMLHttpRequest();
xhr.setRequestHeader({
x-body: JSON.stringify(body),
})
複製代碼
服務端接收時再判斷header中是否有x-body,當時想的這種方式是可行的,但現實很殘酷,這種方式測試時發現抓包都抓不到,說明請求都沒發出來,把body數據改小點,測試是能夠的,這說明qq瀏覽器對header裏數據大小是有限制的,(這就是理論與現實的矛盾的問題,http協議其實對這些都是沒有限制的,但各個瀏覽器會有各自不一樣的限制),這種方式也宣佈流產,此時已經中度蛋疼了。
問題就是qq瀏覽器中post請求時body爲空,須要在頁面返回時有content-type,不然在一些版本的qq瀏覽器中會識別有問題,致使body爲空。
在這個過程當中,我意識到兩個問題