摘要:除非使用了分塊編碼,否則首部就是帶有實(shí)體主體的報(bào)文必須使用的。
背景
新項(xiàng)目上線, 發(fā)現(xiàn)一個(gè)奇怪的BUG, 請(qǐng)求接口有很小的概率返回400 Bad Request,拿到日志記錄的請(qǐng)求的參數(shù)于POSTMAN中測(cè)試請(qǐng)求接口, 發(fā)現(xiàn)能夠正常響應(yīng).
排查過程首先服務(wù)器能夠正常響應(yīng)400 Bad Request, 排除接口故障問題.
對(duì)比日志過程中發(fā)現(xiàn)
{ "hello":"world" }
接口能夠正常響應(yīng)業(yè)務(wù)數(shù)據(jù).
{ "hello":"world", "kw":"我是八阿哥" }
則接口返回400錯(cuò)誤,接口的請(qǐng)求方式均為post json,于是開始review代碼.發(fā)現(xiàn)在發(fā)送請(qǐng)求時(shí)設(shè)置了Content-Length,在含中文字符的情況下接口均返回400,定位到原因.請(qǐng)求的偽代碼如下
let param = { "hello":"world", "kw":"我是八阿哥" } let _options = { headers: { "Content-Type": "application/json", "Content-Length": JSON.stringify(param).length }, url: url, method: "POST", json: true, time: true, timeout: 5 * 1000, body: param } return new Promise((resolve,reject)=>{ request(_options,(error, response, body)=>{ ///XXXX ]) })分析結(jié)果
首先, 來說說什么是Content-Length,在http的協(xié)議中Content-Length首部告訴瀏覽器報(bào)文中實(shí)體主體的大小。這個(gè)大小是包含了內(nèi)容編碼的,比如對(duì)文件進(jìn)行了gzip壓縮,Content-Length就是壓縮后的大小(這點(diǎn)對(duì)我們編寫服務(wù)器非常重要)。除非使用了分塊編碼,否則Content-Length首部就是帶有實(shí)體主體的報(bào)文必須使用的。使用Content-Length首部是為了能夠檢測(cè)出服務(wù)器崩潰而導(dǎo)致的報(bào)文截尾,并對(duì)共享持久連接的多個(gè)報(bào)文進(jìn)行正確分段.
其次,為什么含有中文字符的請(qǐng)求參數(shù)返回400,因?yàn)?b>Content-Length是計(jì)算請(qǐng)求參數(shù)的字節(jié)數(shù),而非字符數(shù).而JSON.stringify(param).length返回的是字符數(shù).含中文字符的情況下
console.log("八阿哥".length) //3, 即3個(gè)字符
console.log(Buffer.byteLength("八阿哥", "utf8")); //9, utf-8編碼下,一個(gè)漢字是3字節(jié)存儲(chǔ)的
導(dǎo)致接口層拿到的Content-Length小于真實(shí)的字節(jié)長度, 因而無法正確的解析數(shù)據(jù), 從而返回400 Bad Request.因此需要將設(shè)置Content-Length的長度改為Buffer.byteLength(JSON.stringify(param),"utf8")
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/26065.html
摘要:背景項(xiàng)目中通過遠(yuǎn)程調(diào)用服務(wù)框架調(diào)用了許多其它的服務(wù)其中有一個(gè)服務(wù)需要升級(jí)其升級(jí)不是版本上的升級(jí)而是整個(gè)服務(wù)重新取了一個(gè)名字使用的也是全新的包但是調(diào)用的方法沒有改變因此在升級(jí)時(shí)只是在調(diào)用服務(wù)類中修改了調(diào)用地址和調(diào)用返回實(shí)體由改為該中返回該調(diào)用 背景 項(xiàng)目中通過遠(yuǎn)程調(diào)用服務(wù)框架調(diào)用了許多其它的服務(wù),其中有一個(gè)服務(wù)wx/subscribe/contract/CircleService 需要升...
摘要:項(xiàng)目組長給我看了一道面試別人的面試題。打鐵趁熱,再來一道題來加深下理解。作者以樂之名本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。 showImg(https://segmentfault.com/img/bVbur0z?w=600&h=400); 剛?cè)肼毿鹿荆瑢儆诠久刃乱幻?,一天下午?duì)著屏幕看代碼架構(gòu)時(shí)。BI項(xiàng)目組長給我看了一道面試別人的JS面試題。 雖然答對(duì)了,但把理由說錯(cuò)了,照樣不及格。 ...
摘要:在群里討論,然后得出了這幾種寫法,感覺是層層遞進(jìn),想了想,最后選擇發(fā)布成文章大頭兒子小頭爸爸叫去吃飯大頭兒子小頭爸爸叫去吃飯大頭兒子小頭爸爸叫去吃飯吃完了背小頭兒子回去正在牽著的手正在吃給所有對(duì)象擴(kuò)展一個(gè)繼承的方法繼承爸爸要繼承人的功能正在 在群里討論JavaScript,然后得出了這幾種寫法,感覺是層層遞進(jìn),想了想,最后選擇發(fā)布成文章 ({ baby : 大頭兒子, ...
摘要:但是在這個(gè)判斷的情況下,則會(huì)很神奇的發(fā)現(xiàn)打印出來了,說明此時(shí)為,為什么呢因?yàn)檫@里執(zhí)行了一個(gè)對(duì)象到布爾值的轉(zhuǎn)換故返回。 ????之前做項(xiàng)目的時(shí)候,總會(huì)處理各式各樣的數(shù)據(jù),來進(jìn)行繪圖。但是當(dāng)后臺(tái)返回一個(gè)空數(shù)組的時(shí)候,頁面中并不會(huì)顯示沒有數(shù)據(jù)的圖。代碼如下: var arr = [] if(arr){console.log(124)}else{console.log(無數(shù)據(jù))} 我明明判斷了...
閱讀 2229·2019-08-30 10:51
閱讀 785·2019-08-30 10:50
閱讀 1463·2019-08-30 10:49
閱讀 3130·2019-08-26 13:55
閱讀 1591·2019-08-26 11:39
閱讀 3412·2019-08-26 11:34
閱讀 1937·2019-08-23 18:30
閱讀 3381·2019-08-23 18:22