一、Session 狀態模式比較
| 模式 | 儲存位置 | 優點 | 缺點 | 適用場景 |
| InProc (預設) | IIS 工作進程記憶體 | 速度最快、支援任意物件 | 回收/重啟遺失、不支援 Web Farm | 單機、開發測試、非關鍵資料 |
| StateServer | 獨立 ASP.NET State Service | 進程隔離、支援 Web Farm | 序列化開銷、單點故障 | 多伺服器、需保留 Session |
| SQLServer | SQL Server 資料庫 | 持久化、高可用、支援叢集 | 延遲最高、需授權 | 企業級、高可用性要求 |
| Custom | 自訂 Provider (Redis, Mongo...) | 彈性最高、效能可調 | 開發成本高 | 高併發、分散式架構 |
web.config 設定範例
<sessionState mode="SQLServer"
sqlConnectionString="Data Source=.;Initial Catalog=ASPState;Integrated Security=True"
cookieless="false" timeout="20" />
二、驗證碼 (CAPTCHA) 完整實作 (.ashx + 頁面)
YZM.ashx - 產生算術驗證碼圖片
<%@ WebHandler Language="C#" Class="YZM" %>
using System;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
public class YZM : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg";
using (Bitmap bmp = new Bitmap(130, 40))
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.White);
Random rnd = new Random();
int n1 = rnd.Next(1, 10);
int n2 = rnd.Next(1, 10);
int ans = n1 + n2;
// 存入 Session (Key: "CaptchaAnswer")
context.Session["CaptchaAnswer"] = ans.ToString();
// 繪製干擾線
for (int i = 0; i < 5; i++)
g.DrawLine(Pens.Gray, rnd.Next(130), rnd.Next(40), rnd.Next(130), rnd.Next(40));
// 繪製文字
string text = $"{n1} + {n2} = ?";
g.DrawString(text, new Font("Consolas", 20, FontStyle.Bold), Brushes.Blue, 5, 2);
bmp.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
public bool IsReusable => false;
}
登入頁面使用
<img id="imgCaptcha" src="YZM.ashx" alt="點擊更換" style="cursor:pointer; vertical-align:middle;" />
<script>
document.getElementById('imgCaptcha').onclick = function() {
this.src = 'YZM.ashx?' + new Date().getTime(); // 防快取
};
</script>
<asp:TextBox ID="txtCaptcha" runat="server" />
<asp:Button ID="btnLogin" runat="server" Text="登入" OnClick="btnLogin_Click" />
後端驗證
protected void btnLogin_Click(object sender, EventArgs e)
{
string userAns = txtCaptcha.Text.Trim();
string correctAns = Session["CaptchaAnswer"]?.ToString();
if (string.IsNullOrEmpty(correctAns) || !userAns.Equals(correctAns, StringComparison.OrdinalIgnoreCase))
{
lblMsg.Text = "驗證碼錯誤";
return;
}
// 驗證通過,進行帳密檢查...
Session.Remove("CaptchaAnswer"); // 一次性使用
}
三、HTTP 協議核心觀念 (面試必考)
- 無狀態:每個 Request 獨立,伺服器不記住 Client。透過 Cookie/Session/Token 維持狀態。
- Request 結構:Request Line (Method URL Version)、Headers、Blank Line、Body。
- Response 結構:Status Line (Version Code Reason)、Headers、Blank Line、Body。
- 常見 Method:GET(查)、POST(增)、PUT/PATCH(改)、DELETE(刪)、HEAD/OPTIONS。
- 狀態碼:2xx 成功、3xx 重導、4xx 客戶端錯誤 (400/401/403/404)、5xx 伺服器錯誤 (500/502/503)。
- 持久連線:HTTP/1.1 預設
Connection: keep-alive,減少 TCP 三向交握開銷。
四、XSS (Cross-Site Scripting) 防護實務
危險控制項
Literal:預設 Mode="Transform" 直接輸出 HTML,**極度危險**。
Label:輸出 <span>,內容經 HTML Encode,較安全。
GridView BoundField:自動 Encode。
防護措施
- 輸出編碼:
Literal.Mode = LiteralMode.Encode 或 HttpUtility.HtmlEncode()。
- 輸入驗證:白名單驗證 (RegularExpressionValidator)、長度限制。
- HttpOnly Cookie:
cookie.HttpOnly = true,JS 無法讀取 Session ID。
- CSP 標頭:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; 限制腳本來源。
- Request Validation:ASP.NET 內建 (
<pages validateRequest="true">) 攔截可疑輸入,不可單靠此機制**,需配合上述措施。
Literal Mode 比較
| Mode | 行為 | 安全性 |
Transform (預設) | 直接輸出,支援 HTML 標籤 | ❌ 危險 |
Encode | HTML Encode 後輸出 | ✅ 安全 |
PassThrough | 同 Transform,不處理 | ❌ 危險 |
五、虛擬路徑 ~ 運算子
- 僅限 **伺服器端控制項** 屬性 (ImageUrl, NavigateUrl, Src, Href 等) 自動解析為應用程式根目錄相對路徑。
- HTML 原生標籤 (
<img src="~/Images/x.jpg">) **不會** 解析,瀏覽器會請求字面路徑導致 404。
- 後端程式碼解析:
VirtualPathUtility.ToAbsolute("~/Images/x.jpg") 或 Page.ResolveUrl("~/Images/x.jpg")。
六、Web 開發核心原則 (摘要)
- 關注點分離:UI (aspx) / 邏輯 (cs) / 資料 (DAL) 分層。
- 單一職責:每個類別/方法只做一件事。
- 介面導向程式設計:依賴抽象而非具體實作,利於測試與替換。
- 防禦性程式設計:永不信任輸入,驗證、編碼、參數化查詢、最小權限。
- 效能意識:分頁、快取、非同步、連線池、減少 ViewState、靜態資源 CDN。
- 安全第一:HTTPS、CSP、XSS/CSRF/SQLi 防護、錯誤訊息不洩露堆疊。