在 WebForms 時代常見的 <%= ... %> 內嵌輸出雖可行,但易產生 XSS 風險且難以維護。本文介紹三種更優雅、安全的資料傳遞方式,適用於 WebForms、MVC 與現代 SPA 架構。
後端將陣列序列化為 JSON 字串,前端直接解析為 JS 物件/陣列。
// 後端 C# (WebForms .aspx.cs 或 MVC Controller)
public string[] Locations = new[] { "台北", "台中", "高雄" };
public string LocationsJson => Newtonsoft.Json.JsonConvert.SerializeObject(Locations);
<!-- 前端 .aspx / .cshtml -->
<script>
// 直接取得強型別 JS 陣列
var locations = <%= LocationsJson %>;
console.log(locations); // ["台北", "台中", "高雄"]
</script>
優點:型別正確、支援多維陣列/物件、自動處理逸出字元。
注意:MVC 中請用 @Html.Raw(Json.Encode(Model.Locations)) 避免雙重編碼。
將 JSON 存放在 DOM 元素的 data-* 屬性,前端模組初始化時讀取並解析。
<div id="map-container" data-locations="<%= LocationsJson %>"></div>
<script type="module">
import { initMap } from './mapModule.js';
const el = document.getElementById('map-container');
const locations = JSON.parse(el.dataset.locations);
initMap(locations);
</script>
優點:關注點分離、不汙染全域命名空間、利於單元測試與 CSP 政策。
前端啟動時呼叫 API 端點取得資料,完全分離前後端部署。
// Web API Controller
[HttpGet]
public IActionResult GetLocations() => Ok(new[] { "台北", "台中", "高雄" });
// 前端
fetch('/api/locations')
.then(r => r.json())
.then(locations => { /* 渲染邏輯 */ });
優點:首屏載入快、資料即時、支援快取策略、前後端可獨立版控。
| 舊式寫法 | 問題 | 建議替代 |
|---|---|---|
for(...) { push("<%= arr[i] %>") } |
XSS 風險、效能差、難除錯 | JSON 序列化一次輸出 |
var arr = new Array(); <% for... %> |
混合伺服端/客戶端邏輯 | 資料屬性或 API 取得 |
JsonConvert.SerializeObject 或 JavaScriptSerializer 確保合法 JSON 格式,避免注入攻擊。script-src 'self' 禁止內嵌 Script,強制採用外部檔案或 Nonce/Hash 機制。選擇哪種方式取決於專案架構:傳統 WebForms 快速改良用方法一;新專案或模組化頁面優先方法二;追求關注點分離與擴展性則採方法三。