bug修复录-qq浏览器中post请求时body为空
近期項目中遇到一個bug,其中解決過程比較有意思,特此記錄下來。有一天看到報警記錄有一個500服務端的錯誤,量很少,一周都不一定有一個,先根據服務器里的本地日志拿到了當時請求的相關信息像UA、cookie什么的,確定了請求是來自iPhone上的qq瀏覽器,因為我們業務在手機瀏覽器里沒有入口,所以這種情況很少。于是找來iPhone下載QQ瀏覽器嘗試復現問題。
bug情景復現
描述: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時用排除法,先確定問題所在
首先排查發post請求過程有沒有問題,因為有可能依賴的某個包在國產QQ瀏覽器上有兼容性問題,但一路排查發起過程都沒什么問題,最后不用依賴包,直接用XMLHttpRequest手寫了個post請求依然不好使,排除了發請求的依賴包的問題。
排查項目是否對發請求有影響,有些內部的監控上報的包可能會對XMLHttpRequest中方法做改寫,于是一路刪除懷疑的依賴包,最后單純返回了一個簡單頁面,頁面內發一個post請求,body依然為空,至此排除了所有依賴包的影響(這個過程很費時間,這個思路不是很好)。
排查到這就有點蛋疼了,Google搜了下看有沒有人和我遇到同樣的問題,發現qq瀏覽器論壇上17年就有人提出這個問題了,相似的帖子大概有七八個,但有官方回應的也就一兩個,回復也只是說讓升級瀏覽器。。。用戶升級瀏覽器還行,開發者得解決問題啊,排查到這已經確定了一點,就是qq瀏覽器肯定對post請求的支持是有問題的。
意識到qq瀏覽器有問題,下意識想針對qq瀏覽器做下兼容處理。開始想post改成get請求,但是post中的body不是簡單地數據結構,如果是以下數據改成get還好,如:
body{name: 'frontend',age: '8',} 復制代碼但是遇到較為復雜的數據結構就不好使了,如:
{times: [123,234,2423,12],favour: {detail: 'sdadfa',}} 復制代碼因為改成get后是通過query來傳遞數據的,query是只支持字符串的;另外這種方式隱隱約約感覺會坑很大,所以排除了這種方式。于是嘗試另一種方式,把body數據放到header里面,反正HTTP協議里對header大小是沒做限制的,所以這樣干的
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為空。
在這個過程中,我意識到兩個問題
總結
以上是生活随笔為你收集整理的bug修复录-qq浏览器中post请求时body为空的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx 认证多个客户端的问题
- 下一篇: vue[源码]你不知道的observe!