Safari瀏覽器在ASP.NET中出現中日韓相容表意文字臭蟲

這幾天花了許多時間在找一隻只有在Apple公司出品的作業系統(例如:MacOS、iOS)中,並使用Safari核心的瀏覽器才會出現的臭蟲。會花很多時間的原因是因為辦公室並沒有擁有MacOS設備的開發環境,因此你沒有辦法單靠使用者等級的設備(iPhone、iPad)來進行F12網路模式來除錯,花大時間去建置Sniffer環境想想又不太值得耗費這麼大的功夫,最後靠著別單位的一台Mac Mini設備直接跑MacOS起來除錯,問題總算是可以被開始被還原以利除錯。

這隻臭蟲會在ASP.NET環境中,使用蘋果公司的Safari瀏覽器時出現,無論是哪個版本都一樣。簡單的來說,當你寫好一個正常可以在InternetExplorer、FireFox、Chrome,甚至是Microsoft Edge下面正確執行的網頁,但是移到iPhone、iPad、MacOS上面的Safari就會出現崩潰。值得一提的是,iPhone上面的Chrome是採用Safari引擎,所以也會產生崩潰,但是MacOs上面的Chrome上面不是採用Safari引擎,所以不會崩潰。

崩潰的提示文字

以下簡列中英文版本的錯誤訊息,讓大家先參考一下:

無效的回傳或回呼引數。已在組態中使用 <pages enableEventValidation="true"/> 或在網頁中使用 <%@ Page EnableEventValidation="true" %> 啟用事件驗證。基於安全性理由,這項功能驗證回傳或回呼引數是來自原本呈現它們的伺服器控制項。如果資料為有效並且是必須的,請使用 ClientScriptManager.RegisterForEventValidation 方法註冊回傳或回呼資料,以進行驗證。
Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

思考

看到你的網頁出現這樣的錯誤訊息,接下來你的腦袋會開始引發一連串的思考風暴。你會開始找這個錯誤引發的原因,當然有經驗的程式設計師也會馬上意會到這個代表前端有伺服器控制項(Server Control)的內容被改到了。

然後你開始去翻程式碼,怎麼看都找不出到底哪裡可能會有Javascript等級的Code去改到前端?

然後你開始去Google網路的文章,但是每一篇都是新手等級的廢文,都在教你用IsPostback把程式碼隔開。

然後你開始打開瀏覽器的Developer Mode,開始Trace你的Javascript以及拆解Postback參數。

然後頭昏腦脹百思不得其解的你,突然想到,不對啊!我找這些東西如果會出現錯誤,那為何只有Safari會出錯?其他瀏覽器都是正確的?

別找了,臭蟲就在Safari瀏覽器身上

這隻蟲外國人永遠不會發現,只有在使用CJK(Chinese, Japanese and Korean)語言的國家才會出現,最主要的問題是出現在「中日韓相容表意文字」(CJK Compatibility Ideographs),也就是Unicode字碼區域落在「F900~FAFF」,這區塊會把各國編碼重複的文字往這邊丟,例如日本有一些漢字跟繁體、簡體的中文重複,這個區塊中就會記錄這些文字,以利文字文件的流通與相容。那麼,這個字區跟我們要討論的Bug有何關係?

當你的ASP.NET Server Control(也就是有出現runat="server"屬性的控制項)內容裡面,若有內文文字落在CJK Compatibility Ideographs字元區,當你將這個控制項存在的網頁進行Postback、Auto Postback,就會引爆這樣的災難。最可能聽到的話是,啊你這個網頁為何我用iPhone、iPad進去,就會發生錯誤?

解決方案

舉例來說,你看得出下面這兩個字有何不一樣嗎?

歷 6B77
歷 F98C << 你塞入這個字元就會引爆炸彈

我自己推論Safari在PostBack的時候,會自己「假敖」(台語:自己覺得自己很厲害)把落在CJK Compatibility Ideographs區塊的字元,自己替換回正式的字元,導致ASP.NET在進行__VIEWSTATE或__EVENTVALIDATION的雜湊取回驗證時,發現有被修改過,因而引爆一連串的靈異現象。不過因為這個Bug實在有夠鳥浪費我太多時間,所以我也就沒有再多花時間去驗證就是了。

看不出字元的差異嗎?我這邊有翻到一個好心的日本人整理的對照表,自己參考一下吧!CJK 互換漢字表或者是Unicode官方的CJK Compatibility Ideographs PDF檔案。

SafariBrowser ASP.NET PostBack EventValidation Bug Error CJK_CompatibilityIdeographs Unicode