OkHttp header 中不能傳中文的坑
阿新 • • 發佈:2019-02-05
運營同事反饋說,有不止一個魅族使用者說,登入不上我們的應用;我聽到這個問題,很自信的回覆他,肯定是使用者的網路有問題,最多是後端的介面掛了,和app 沒有關係。但是bugly上看了一下,突然發現有個bug
IllegalArgumentException: Unexpected char ... in header value: ... at com.squareup.okhttp.Headers$Builder.checkNameAndValue (Headers.java:295)
我趕緊到魅族官方網站上下載了新春特別版的Rom,安裝,開啟,果然網路請求失敗,崩潰了.
問題是這樣的,我們的UA中存在上傳手機系統版本號的欄位:android.os.Build.DISPLAY,這個本無問題,但是魅族春節的時候發了一個新春特別版本,他的系統版本號為:Flyme OS 5.1.3.0A 新春特別版.
這個鍋我不能接,趕緊查了okhttp的issues
有個印度哥哥說:
Non-ASCII characters are allowed according to both the original and updated HTTP 1.1 specs. The updated spec recommends against using non-ASCII characters for newly-defined headers, but clearly they're allowed: Historically, HTTP has allowed field content with text in the ISO-8859-1 charset [ISO-8859-1], supporting other charsets only through use of [RFC2047] encoding. In practice, most HTTP header field values use only a subset of the US-ASCII charset [USASCII]. Newly defined header fields SHOULD limit their field values to US-ASCII octets. A recipient SHOULD treat other octets in field content (obs-text) as opaque data. Because of the way UTF-8 is encoded, all codepoints above 127 are composed of bytes whose values are 128 or greater, which means they should pass through untouched. The only characters you have to be careful with are ASCII control characters and, in certain situations, spaces, quotes, and backslashes.
不翻譯了,簡單來說就是不支援中文
Hi, this restriction about just ASCII chars is very strange, we support chinese users etc... So almost all of our request fail when we try to send some chinese value using the header. This works fine in the HttpRequest apache. Why this restriction?
用了那麼久的OkHttp,第一次知道這個坑,望各位繞過,但是能看到這篇bolg的應該已經中招了,下面怎麼解決尼?
避免出現中文
我的解決方式:
private String getOsDisplay() {
String osStr = StringUtil.removeSpace(android.os.Build.DISPLAY);
if (osStr.length() < osStr.getBytes().length) {
try {
return URLEncoder.encode(StringUtil.removeSpace(android.os.Build.DISPLAY), "UTF-8");
} catch (Exception e) {
e.printStackTrace();
return "";
}
} else {
return osStr;
}
}