input標籤有中文郵箱後綴名引發的問題

前提介紹

最近,在公司的某個項目中,測試人員發現了一個頗有意思的Bug。當用戶的我的資料頁面的郵箱聯繫方式是中文後綴時,例如"mi@測試.com",在Android原平生臺上會顯示亂碼的現象,而在瀏覽器中顯示則正常,結果以下面兩張圖所示。在另外一個同事尋找資料無果的狀況下,因而,我開始了一步步分析這個問題的過程。
image.png
上圖是Android設備
image.png
上圖是瀏覽器中
html

分析過程    

由於兩個環境中調用的都是同一個接口返回的數據,因此以我的多年的工做經驗來看,這個問題多是編碼方面的問題。因而,我列出瞭如下幾種狀況:瀏覽器

  1. Web端進行了轉碼,而後傳入到後臺服務器中,Android端拿到數據後,因爲編碼不一樣,因此出現中文部分出現了亂碼。
  2. Web端沒有轉碼,可是後臺服務器進行了轉碼,Android端拿到數據後,因爲編碼不一樣,因此出現中文部分出現了亂碼。
  3. Web端和後臺服務都沒有轉碼,Android端的輸入框控件內部進行了一次轉碼,而後致使中文部分出現了亂碼。
  4. Web端和後臺服務器都進行了轉碼,也就是進行了兩次轉碼,而後致使Android端出現中文部分了亂碼的緣由。

針對以上的幾種狀況,我分別詢問了各位同事和抓包看返回的數據,發現:一、Web端、服務器端都沒有進行轉碼操做。二、在出現亂碼的Android端,拿到的數據就是接口返回的原始數據。並且,我也嘗試過對幾種常見的編碼進行轉換操做,看看能不能找到問題所在,可是都不是我想要的結果。那,問題究竟在哪?
服務器

深刻分析的過程

在初次分析無果的狀況下,我開始考慮會不會是由於Web端的使用的第三方框架的緣由。由於Web端使用了Element UI,有沒有可能Element UI對<input />標籤進行了二次封裝,並進行了轉碼操做?同時,經Web端的同事提醒,<input />標籤的type屬性爲"email"。因而,我決定,我直接新建了一個新的HTML文件,爲了避免受其它影響,裏面就只有一個<input />標籤。
框架

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input type="email" />
</body>

</html>


而後,在Chrome 瀏覽器中打開,輸入測試字段"mi@測試.com"。結果顯示一切正常,中文依然正確顯示,彷佛沒有任何問題。可是本着要打破砂鍋問到底的精神,我試着在瀏覽器中改了一下標籤的type值,我嘗試着將"email"改爲"text"。沒想到,問題復現了。

https://www.bilibili.com/vide...ide

將type="email"改爲type="text"之後,瀏覽器中中文部分會出現亂碼,而再改回去之後,顯示又一切正常。另外一方面,我試着在在Chrome控制檯中獲取input值,看看原始值究竟是什麼。結果,也有了驚奇的發現。
image.png    此時input標籤的type值依然是"email",但在控制檯中打印出來的結果竟然是亂碼的字符串,如今看來,問題的關鍵點頗有可能就是在這個type="email"上!
測試

爲何是type="email"?

有過Web開發的同窗們應該對這個屬性是很熟悉的了,至於type的其它類型,就不在本文中闡述了,咱們直接看MDN上關於<input type="email">的相關資料,試着去了解一下,當type="email"的時候,瀏覽器究竟作了什麼?(更多細節能夠點擊這個連接進行查看)。網站


帶有 "email" (電子郵箱)類型標記的輸入框元素()可以讓用戶輸入或編輯一個電子郵箱地址,此外,若是指定了multiple屬性,用戶還能夠輸入多個電子郵箱地址。在表單提交前,輸入框會自動驗證輸入值是不是一個或多個合法的電子郵箱地址(非空值且符合電子郵箱地址格式). CSS僞標籤 :valid 和 :invalid 可以在校驗後自動應用。

根據引用MDN網站上的文字的描述,個人一個猜測是,多是瀏覽器在作驗證的時候進行了轉碼操做,同時,我又看到網頁中的這個相關描述。而後,我點擊了DOMString來進行更深刻的瞭解。搜索引擎

image.png

DOMString 是一個UTF-16字符串。因爲JavaScript已經使用了這樣的字符串,因此DOMString 直接映射到 一個String

看到這兩個描述,我第一反應是,難道"mix@測試.com"是被轉碼成了UTF-16?可是,轉碼後的字符串並非常見的UTF-16的格式。因此直覺告訴我,事情沒有那麼簡單,這不是我想要的結果。因而我繼續在當前的MDN網頁上查看相關資料,在網頁的下端,一段內容引發了個人注意。引發我注意的不只僅是那段正則,還有下面的提示--W3C bug 15489
image.png
打開連接後我發現W3C bug 15489 是2012年由一位叫 Mathias Bynens 外國工程師 提出來的問題,在這個討論問題的帖子的頁面中,我驚喜的發現,這個網頁中所提的bug正是我苦苦尋找的問題所在。
image.png
順着這個結果,我發現關鍵的線索--Punycode!我立馬打開的新的網頁,找一個在線Punycode編碼的網站。BingGo!
image.png
編碼

什麼是Punycode?

那麼,問題的因此在看來就是這個Punycode了,那什麼是Punycode呢?引用百度百科的裏的解釋:spa

Punycode(譯爲:域名代碼)是一種表示Unicode碼和ASCII碼的有限的字符集。例如:「münchen」(德國慕尼黑)會被編碼爲「mnchen-3ya」。

同時,瞭解到一個新的知識點--IDNs(國際化域名 Internationalized Domain Names)。早期的DNS是隻支持英文域名解析。在IDNs推出之後,爲了保證兼容之前的DNS,因此,對IDNs進行Punycode轉碼,轉碼後的Punycode就由26個字母+10個數字,還有「-」組成。
順着這個,我接着往下看,這個頁面裏發現了一個更有意思和詳細的資料。
image.png

最後的總結

因此,通過幾乎1個小時的時間,通過各類資料的彙總,這個問題終於被摸清楚了。
在瀏覽器中type屬性爲email的input標籤能正常顯示中文後綴的緣由,是由於現代瀏覽器自動加入中文域名的轉碼。正如上文所說,是瀏覽器軟件裏面主動加入了中文域名自動轉碼,因此中文後綴纔會顯示正常。同時,這也就解釋了爲何在type="email"的狀況下。瀏覽器控制檯中獲取的value會依然是亂碼後的字符串。那麼,既然知道問題的所在,解決的方法天然也很簡單了,經過搜索引擎或者本身寫一個關於Punycode轉碼的方法應該就能將問題順利解決了。

相關文章
相關標籤/搜索