記一次排查:介面返回值寫入excel後,從單元格copy出來的資料會帶有多重引號的問題

測不準發表於2023-05-18

在專案裡剛好有3個服務,同一個閘道器內層的3個服務,兩個php的,一個golang的,為了提高負載以及進行分流,部分客戶的介面呼叫會被閘道器自動分配到go服務。

恰好為了測試,我寫了一個全量使用者的生產、測試環境呼叫介面返回結果進行對比的指令碼,於是發現了題中的問題:兩個php服務裡的介面返回值寫入xlsx後,直接copy出來是正常的json串,golang的介面返回值copy出來變成雙重引號如圖

 

排查過程:

1、先透過python的requests請求介面直接列印出返回值,看看是否是兩個雙引號,結果發現php跟go服務都是正常的json串。

 

2、繼續排查,猜想問題會不會出現編碼傳輸格式上,於是對比php跟go介面響應標頭。

  php服務響應頭如下:

  

  go服務應頭如下

  

  go跟php響應頭的差別只在於兩點:php多了TimeStamp,Content-Type裡面多了charset=utf-8。

  首先排除TimeStamp,從名稱上就可以看出來不會對返回值格式或內容有任何影響;

  然後嘗試用flask編寫兩個介面,Content-Type裡面分別為application/json、application/json; charset=utf-8,寫入excel後發現並沒有任何不同。

 

3、響應頭也沒問題,繼續猜想會不會是go服務程式碼缺陷,介面在return response之前並沒有序列化,而是直接返回了object物件

  我們先了解一個概念:序列化與反序列化

  序列化是把程式物件轉換為位元組序列的過程,反序列化就是把位元組序列恢復為程式物件的過程。

  因為不同的客戶端、服務端可能使用的語言不同,為了相容都是用序列化之後的資料進行傳輸,比如前端js將頁面引數序列化之後傳遞給後端java服務。

  開始實驗,本地flask直接返回字典{"username": username, "password": password},寫入excel的居然真的出現了兩個雙引號。

  

 

4、於是讓開發排查程式碼裡是不是沒有作序列化,但是出人意料的是,go程式碼裡是做了序列化才返回的。

  所以上面的猜想都不成立,研究一度陷入僵局,直到...

 

5、偶然注意到copy出來的返回值尾巴上有個莫名其妙的換行。

  

  根據以前經常寫json資料入csv、xlsx檔案的經驗,就算是格式化後加了多個引號的json資料(例如pandas的to_csv方法裡的quoting引數即可控制是否加引號),也不可能加換行符。

  所以猜想會不會是返回值多了個隱形的換行符,然後在pacharm的cmd裡調一下介面看看,果然go服務返回體尾巴上換行了,而php則不會

  

 

6、於是在寫入excel之前把返回值rstrip()一下做最後的確認,結果從excel複製出來的資料真的沒有多重引號了

 

至此,揪出來這個go服務的bug!

 

相關文章