使用者每次重新整理頁面 (或首次載入) 時,自動隨機顯示指定資料夾下的一張圖片。適用於廣告橫幅、驗證碼背景、隨機封面等場景。
public void ProcessRequest(HttpContext context)
{
// 1. 圖片資料夾路徑 (相對應用程式根目錄)
string folder = context.Server.MapPath("~/img/");
// 2. 取得所有 jpg 檔案
string[] files = Directory.GetFiles(folder, "*.jpg");
if (files.Length == 0)
{
context.Response.StatusCode = 404;
return;
}
// 3. 隨機選取一張
var rnd = new Random();
string selected = files[rnd.Next(files.Length)];
// 4. 設定回應標頭並輸出二進位內容
context.Response.ContentType = "image/jpeg";
context.Response.WriteFile(selected);
context.Response.End();
}
<!-- 直接指向處理常式/Action -->
<img src="/RandomImage.ashx" alt="隨機圖片" />
<!-- MVC -->
<img src="@Url.Action("RandomImage", "Home")" />
<!-- Razor Pages -->
<img src="/RandomImage" />
public class RandomImageHandler : IHttpHandler
{
private static readonly string[] _allowedExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".webp" };
private static readonly Random _rnd = new Random();
private static string[] _cachedFiles;
private static DateTime _lastScan = DateTime.MinValue;
private static readonly object _lock = new object();
public bool IsReusable => true;
public void ProcessRequest(HttpContext context)
{
// 定期掃描資料夾 (每 5 分鐘),避免每次請求都 I/O
EnsureFileListCached(context);
if (_cachedFiles == null || _cachedFiles.Length == 0)
{
context.Response.StatusCode = 404;
return;
}
string file = _cachedFiles[_rnd.Next(_cachedFiles.Length)];
string ext = Path.GetExtension(file).ToLowerInvariant();
string mime = ext switch
{
".jpg" or ".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".webp" => "image/webp",
_ => "application/octet-stream"
};
// 禁用快取:確保每次重新整理都重新請求
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetNoStore();
context.Response.ContentType = mime;
context.Response.WriteFile(file);
}
private void EnsureFileListCached(HttpContext context)
{
if (DateTime.UtcNow - _lastScan < TimeSpan.FromMinutes(5) && _cachedFiles != null)
return;
lock (_lock)
{
if (DateTime.UtcNow - _lastScan < TimeSpan.FromMinutes(5) && _cachedFiles != null)
return;
string folder = context.Server.MapPath("~/img/");
if (Directory.Exists(folder))
{
_cachedFiles = Directory.GetFiles(folder)
.Where(f => _allowedExtensions.Contains(Path.GetExtension(f).ToLowerInvariant()))
.ToArray();
}
else
{
_cachedFiles = Array.Empty();
}
_lastScan = DateTime.UtcNow;
}
}
}
<%
Randomize
Dim url, total
total = 10 ' 圖片總數,需手動維護或掃描資料夾
url = "images/pic" & ((Int(Rnd() * 100000) Mod total) + 1) & ".jpg"
' 輸出: images/pic1.jpg ~ images/pic10.jpg
%>
<img src="<%=url%>" />
| 問題 | 原因 | 解決 |
|---|---|---|
| 圖片不顯示/斷圖 | 路徑錯誤、副檔名不符、MIME 未設定 | 用 Server.MapPath 取得絕對路徑;Response.ContentType 必須精確 |
| 瀏覽器快取導致不隨機 | 預設快取策略 | 加入 Cache-Control: no-store, no-cache, must-revalidate 或 URL 加查詢字串 ?v=Guid |
| 高併發下 Random 重複/效能差 | Random 非執行緒安全、頻繁 I/O | 使用 ThreadLocal<Random> 或 RandomNumberGenerator;快取檔案清單 |
| 大圖載入慢 | 未壓縮、無 CDN | 預先產生縮圖、啟用 IIS 動態壓縮、上傳至 Blob 儲存/CDN |
img.src,減輕伺服器壓力。核心邏輯極簡:掃描資料夾 → 隨機挑選 → 設定 MIME → 二進位輸出。生產環境務必加入快取控制、檔案清單快取、執行緒安全隨機數。若流量大,建議前端隨機或 CDN 直連,降低應用伺服器負載。