發現 ASP.NET Core 有個特性造成困擾。

我們都知道在 cshtml 以 @textFromServerSide 嵌入字串時,預設會被 HtmlEncode 以防止 Cross-Site Scripting 攻擊,如要將字串視為 HTML 標籤處理需額外呼叫 Html.Raw()。但在 ASP.NET Core 裡,結果跟我原本想像不同,例如以下 cshtml,表面上看來正常,中文正常顯示:

@{
    Layout = null;
}
<html>
<body>
    <div>
        Chinese Text = @("<b>中文測試</b>")
    </div>
</body>
</html>

檢視網頁原始碼卻讓我大吃一驚,中文字元都被轉成 &#xhhhh; 形式! 若以 UTF-8 編碼計算,每個中文字元由 3 Bytes 變成 8 Bytes 增肥近三倍,而更令人困擾的一點,原始碼裡的中文字消失讓網頁偵錯難度驟升好幾個等級。

爬文找到解法,Prevent Cross-Site Scripting (XSS) in ASP.NET Core - Microsoft Docs 文件提到 ASP.NET Core 的 TagHelper 及 HtmlHelper 預設會將所有非拉丁字元都當成特殊符號進行編碼,但此一設計對中文、西里爾文(斯拉夫語族)網頁開發者很不友善。所幸這個行為可透過設定調整,前幾天談 UrlEncode 時提到 .NET Core 新推出的 System.Text.Encodings.Web.HthmlEncoder 就用在這裡。而修改方法為在 Startup.cs ConfigureServices() 加入以下程式片段,將 ASP.NET Core cshtml 透過 DI 取得的 HtmlEcoder 換成我們的自訂版本:

services.AddSingleton<HtmlEncoder>(HtmlEncoder.Create(allowedRanges: new[] { UnicodeRanges.BasicLatin,     UnicodeRanges.CjkUnifiedIdeographs }));

自訂版 HtmlEcoder 將基本拉丁字元與中日韓字元納入允許範圍不做轉碼。

經過這番手腳,網頁原始碼總算清爽多了,阿彌陀佛~

The Chinese characters are encoded as & #xhhhh format by default in ASP.NET Core view. Using HtmlEcoder can resolve the problem.


Comments

# by Cloud

我是用全都不轉碼 services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All));

# by <>

<>

# by TCK

若是在原始碼還有發現被轉碼的文字可至 www.codetable.net 快速查詢Unicode Group 例如全形「!」&#xFF01,直接用hex碼去搜尋,例:https://www.codetable.net/hex/ff01 會顯示Halfwidth and Fullwidth Forms,再去對應UnicodeRanges屬性即可 全形空白 &#x3000 屬於 CJK Symbols and Punctuation,即使 UnicodeRanges.All 也無法轉碼,等高人補遺

# by nick

說明1111

Post a comment