okhttp3 請求頭不能為中文的坑
對原始碼有一定的瞭解,以為基本可以駕馭了,誰知道,坑來了。
問題描述:
上線介面的某一天,有使用者報障,說登入不上,而且陸續有報障。
通過log 發現登入不上,都有一個類似的報錯:
“java.lang.IllegalArgumentException: Unexpected char 0x514d at 4 in wifiSsid value: "360免費WiFi-DP" at ”
什麼?怎麼和wifiSsid有關係了?後來查了一下程式碼,發現確實在登入介面上通過請求頭的形式上傳了 wifissid, 也就是連線的wifi的名字。Exception描述是第四個 char ,也就是“免”字?難道是因為中文的原因?當時是這麼猜測的。
原始碼查詢
猜測並不能作為判斷的標準,然後做了一下測試,果然連線含義中文名字的wifi就有問題,也就是不能新增中文到請求頭裡面。這是為什麼呢?最後還是通過原始碼進行的求證:
在okhttp的原始碼Header.java,發現set 和add header, 都會有這個判斷:
private void checkNameAndValue(String name, String value) {
if (name == null) throw new NullPointerException("name == null");
if (name.isEmpty()) throw new IllegalArgumentException("name is empty");
for (int i = 0, length = name.length(); i < length; i++) {
char c = name.charAt(i);
if (c <= '\u0020' || c >= '\u007f') {
throw new IllegalArgumentException(Util.format(
"Unexpected char %#04x at %d in header name: %s", (int) c, i, name));
}
}
if (value == null) throw new NullPointerException("value == null");
for (int i = 0, length = value.length(); i < length; i++) {
char c = value.charAt(i);
if ((c <= '\u001f' && c != '\t') || c >= '\u007f') {
throw new IllegalArgumentException(Util.format(
"Unexpected char %#04x at %d in %s value: %s", (int) c, i, name, value));
}
}
}
嗷,No,果然是這樣,踩到深坑了。無論是header的 Key 和Value都是不能含有中文的,一旦判定為有中文的出現,就會丟擲異常,中斷請求。
後面想了一下,以前使用okhttp2的時候,也有上傳相同的請求頭,為什麼就沒有這個問題呢?也同樣去檢視了一下okhttp2的原始碼,發現這個判斷是okhttp3才有的,okhttp2其實並沒有這個判斷。
解決方案:
解決方案有以下幾種:
- 不要傳了(當然這個不符合需求)
- 把原始碼這個地方改了(也不是太好,不知道會不會引起其他問題)
- 把中文 encode以下(相對較好的辦法):
ssid = URLEncoder.encode(ssid);
總結
遇到問題不可怕,主要是要做好分析,及時解決,多做總結,避免後門再次踩同樣的坑。
相關文章
- URL請求不能解決中文請求的問題
- Http請求-okhttp3基本用法HTTP
- 淺析okHttp3的網路請求流程HTTP
- 有趣的請求引數/請求頭
- OkHttp3原始碼解析(一)之請求流程HTTP原始碼
- TCP 請求頭TCP
- ajax中設定請求頭和自定義請求頭
- SpringCloud OpenFeign Post請求的坑SpringGCCloud
- axios的post請求爬坑iOS
- SpringMVC處理請求頭、響應頭、編碼行為SpringMVC
- 請求OpenFeign的GET請求時,請求為何失敗?
- HTTP請求頭與響應頭HTTP
- GET請求引數為中文時亂碼分析
- http請求頭與響應頭的應用HTTP
- python爬蟲請求頭Python爬蟲
- 你以為你請求的就是你想請求的嗎?
- HTTP請求頭和響應頭詳解HTTP
- 解決webpack不能匹配post請求的問題Web
- axios躺坑之路:cookie,簡單請求與非簡單請求。iOSCookie
- 請求協議中的content-type頭協議
- HTTP請求頭的Content-Type欄位HTTP
- Python中get、post請求詳解(HTTP請求頭、狀態碼)PythonHTTP
- HTTP常用請求頭大揭祕HTTP
- 關於常用的http請求頭以及響應頭詳解HTTP
- 不能顯式攔截ajax請求的302響應?
- 瀏覽器如何將你的http請求轉為https請求?瀏覽器HTTP
- 自定義的請求頭,你去哪裡了?
- 請求報415的異常,通常都是請求頭Headers的Content-Type沒有配置對Header
- java webservice 帶請求頭方式處理JavaWeb
- 利用Referer請求頭防止“盜鏈”-JavawebJavaWeb
- http請求頭個欄位解釋HTTP
- 安卓okhttp3進行網路請求,一個簡單的登入頁面的實現安卓HTTP
- yaml 檔案裡的中文,以 json 格式請求抓包為什麼是 unicodeYAMLJSONUnicode
- 說說 HTTP 常見的請求頭有哪些? 作用?HTTP
- 判斷請求是否為Ajax請求的小妙招
- 小程式的填坑小技巧之網路請求改造
- 使用Python獲取HTTP請求頭資料PythonHTTP
- Nginx轉發導致請求頭丟失Nginx
- MDN新增“HTTP有條件請求”標頭HTTP