雖然 404 錯誤頁面與 301 重導向功能不同,但兩者都是 SEO 與使用者體驗的關鍵。本文說明如何在 ASP.NET 中正確實作:回傳真正的 HTTP 404 狀態碼(而非 200/302),以及標準的 301 永久重導向。
<!-- 錯誤示範:只會回傳 302 Found 或 200 OK -->
<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="404.aspx" />
</system.web>
</configuration>
問題: 搜尋引擎收到 200 或 302 狀態碼,會認為頁面存在並建立索引,導致大量重複內容,降低網站信任度。
// 404.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
// 關鍵:明確設定 HTTP 狀態碼為 404
Response.Status = "404 Not Found";
Response.StatusCode = 404;
// 可選:記錄錯誤 URL 供後續分析
// Log4Net.Error($"404 Not Found: {Request.Url}");
}
使用 HttpWatch、Fiddler 或瀏覽器開發人員工具(Network 標籤)確認回應標頭包含:
HTTP/1.1 404 Not Found
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.StatusCode = 301;
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", "https://www.new-domain.com"); // 目標網址
Response.End();
}
// Global.asax.cs - Application_BeginRequest
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string oldUrl = Request.Url.ToString().ToLower();
// 範例:舊網域導向新網域
if (oldUrl.Contains("www.old-domain.com"))
{
string newUrl = oldUrl.Replace("www.old-domain.com", "www.new-domain.com");
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", newUrl);
Response.End();
}
// 範例:HTTP 強制導向 HTTPS
if (!Request.IsSecureConnection)
{
string httpsUrl = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
Response.Clear();
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", httpsUrl);
Response.End();
}
}
| 特性 | 404 Not Found | 301 Moved Permanently |
|---|---|---|
| 用途 | 資源不存在 | 資源永久移動到新位置 |
| 搜尋引擎行為 | 從索引中移除 | 轉移權重到新網址,更新索引 |
| 瀏覽器快取 | 不快取 | 會快取導向目標 |
| 適用情境 | 刪除頁面、錯誤連結 | 網域遷移、網址正規化、HTTPS 強制 |
// Startup.cs - Configure
app.UseStatusCodePagesWithReExecute("/Error/{0}"); // 404 導向自訂頁面
// Controller 中回傳 301
return RedirectPermanent("https://www.new-domain.com"); // 內建 301
// 或使用 Middleware 處理 HTTPS 重導向
app.UseHttpsRedirection();
正確的 HTTP 狀態碼是 SEO 基石。404 頁面必須回傳 404 狀態碼,301 重導向必須包含 `Location` 標頭與 301 狀態碼。避免使用 `Response.Redirect`(預設 302)或僅設定 `customErrors` 而不設定狀態碼的錯誤做法。