Response.Redirect("url") 發送 HTTP 302 回應,瀏覽器預設在當前視窗載入新網址。若需在新視窗/分頁開啟,必須在客戶端觸發 window.open(),伺服器端無法直接控制瀏覽器視窗行為。
最簡單粗暴:讓整個表單提交動作在新視窗進行,所有 Response.Redirect 皆會在新視窗開啟。
<!-- 宣告式 -->
<form id="form1" runat="server" target="_blank">
<!-- 或程式碼後置 -->
protected void Page_Load(object sender, EventArgs e)
{
form1.Target = "_blank";
}
缺點:頁面上所有 PostBack(按鈕、分頁、下拉選單自動回傳)都會開新視窗,體驗極差。
僅在特定按鈕點擊時將 form.target 設為 "_blank",其他按鈕回傳前重設為空字串(同視窗)。
<asp:Button ID="btnNewWindow" runat="server" Text="新視窗開啟" OnClick="BtnNewWindow_Click" />
<asp:Button ID="btnSameWindow" runat="server" Text="本視窗開啟" OnClick="BtnSameWindow_Click" />
protected void Page_Load(object sender, EventArgs e)
{
// 關鍵:在客戶端 click 事件中切換 target
btnNewWindow.Attributes["onclick"] = "this.form.target='_blank';";
btnSameWindow.Attributes["onclick"] = "this.form.target='';";
}
protected void BtnNewWindow_Click(object sender, EventArgs e)
{
Response.Redirect("https://example.com/new-page");
}
protected void BtnSameWindow_Click(object sender, EventArgs e)
{
Response.Redirect("https://example.com/same-page");
}
原理:瀏覽器提交表單前執行 onclick 腳本修改 form.target,導向行為隨之改變。PostBack 完成後瀏覽器載入新頁面,target 自動重置。
在伺服器端產生 window.open(url, target, features) 腳本,註冊為啟動腳本,瀏覽器渲染頁面時自動執行。
public static class RedirectHelper
{
///
/// 在新視窗開啟網址
///
/// HttpResponse
/// 目標網址(相對或絕對)
/// 視窗名稱:_blank, _self, _parent, _top 或自訂名稱
/// window.open 第 3 參數,如 "width=800,height=600,resizable=yes,scrollbars=yes"
public static void Redirect(this HttpResponse response, string url, string target, string windowFeatures)
{
if (string.IsNullOrEmpty(target) || target.Equals("_self", StringComparison.OrdinalIgnoreCase))
{
response.Redirect(url); // 同視窗直接用原生 Redirect
return;
}
Page page = HttpContext.Current.Handler as Page;
if (page == null)
throw new InvalidOperationException("無法取得 Page 實例,確認在頁面生命週期中呼叫。");
url = page.ResolveClientUrl(url); // 處理相對路徑
string script = string.IsNullOrEmpty(windowFeatures)
? $"window.open('{url}', '{target}');"
: $"window.open('{url}', '{target}', '{windowFeatures}');";
// 使用 ScriptManager 支援 UpdatePanel 非同步回傳
ScriptManager.RegisterStartupScript(page, typeof(Page), "RedirectNewWindow", script, true);
}
}
// 1. 簡單新視窗
Response.Redirect("~/Report.aspx?id=1", "_blank", "");
// 2. 自訂視窗大小與功能
Response.Redirect("~/PrintPreview.aspx", "_blank", "width=1024,height=768,resizable=yes,scrollbars=yes,status=yes");
// 3. 命名視窗(重複點擊不會開多個視窗)
Response.Redirect("~/Chat.aspx", "ChatWindow", "width=400,height=500");
| 寫法 | 行為 | 適用場景 |
|---|---|---|
Response.Redirect(url, true) | 同視窗導向,終止目前頁面執行 | 一般頁面跳轉 |
Response.Write("<script>window.open('url','_blank')</script>") | 原視窗保留,新開視窗 | 簡單需求,但會輸出在頁面中,可能被瀏覽器攔截 |
Response.Write("<script>window.location='url'</script>") | 同視窗導向(不觸發 onunload) | 特殊導向需求 |
Server.Transfer("url") | 伺服器端轉移,網址列不變 | 同應用程式內頁面傳遞 Context |
window.showModalDialog() | 模態對話框(IE 專屬,已棄用) | 舊版 IE 專案維護 |
window.showModelessDialog() | 非模態對話框(IE 專屬,已棄用) | 舊版 IE 專案維護 |
ScriptManager.RegisterStartupScript。localStorage、sessionStorage 或 URL 參數,而非依賴 window.opener(受同源策略限制)。ASP.NET 伺服器端無法直接指示瀏覽器「在新視窗開啟」,必須透過客戶端機制實現。設定表單 target="_blank" 是最原生、最不易被攔截的方式;配合按鈕層級的 onclick 切換,可精準控制哪些動作開新視窗。對於需要自訂視窗特性的場景,封裝 window.open 的擴充方法提供最佳開發體驗。選對方法,能兼顧使用者體驗與瀏覽器相容性。