測試網址
https://www.example.com:8080/web/index.aspx?category=books&id=123#section2
C# 伺服端 (ASP.NET Web Forms / MVC / Core)
| 屬性/方法 | 回傳值 | 說明 |
Request.Url.AbsoluteUri | https://www.example.com:8080/web/index.aspx?category=books&id=123#section2 | 完整 URL (含片段 # 之後內容**瀏覽器不傳送至伺服器**,此處實際不含 fragment) |
Request.Url.AbsolutePath | /web/index.aspx | 路徑 (不含查詢字串、主機) |
Request.Url.Host | www.example.com | 主機名稱 |
Request.Url.Authority | www.example.com:8080 | 主機 + 埠號 |
Request.Url.Scheme | http | 協定 |
Request.Url.Port | 8080 | 埠號 (int) |
Request.Url.Query | ?category=books&id=123 | 查詢字串 (含 ?) |
Request.Url.LocalPath | /web/index.aspx | 同 AbsolutePath |
Request.Url.PathAndQuery | /web/index.aspx?category=books&id=123 | 路徑 + 查詢字串 |
Request.Url.Fragment | "" (空字串) | **永遠為空** — 片段識別碼 (#...) 瀏覽器不送至伺服器 |
Request.RawUrl | /web/index.aspx?category=books&id=123 | ASP.NET 特有:原始 URL (路徑+查詢),不含主機 |
Request.Path | /web/index.aspx | ASP.NET Core:路徑 |
Request.QueryString | category=books&id=123 | 查詢字串集合 (NameValueCollection / IQueryCollection) |
實用組合
// 取得網站根目錄 URL (含應用程式路徑)
string baseUrl = $"{Request.Url.Scheme}://{Request.Url.Authority}{Request.ApplicationPath.TrimEnd('/')}";
// 結果: https://www.example.com:8080/web (若為虛擬目錄)
// 重導向保持查詢字串
Response.Redirect(Request.RawUrl); // Web Forms
return LocalRedirect(Request.Path + Request.QueryString.ToString()); // Core
JavaScript 客戶端
| 屬性/方法 | 回傳值 | 說明 |
window.location.href | 完整 URL (含 #fragment) | 最常用、可讀寫 (設定即跳轉) |
document.URL | 完整 URL (唯讀) | 同 location.href 但唯讀 |
location.origin | https://www.example.com:8080 | 協定+主機+埠 (無路徑) |
location.protocol | http: | 協定 (含冒號) |
location.host | www.example.com:8080 | 主機+埠 |
location.hostname | www.example.com | 僅主機名 |
location.port | 8080 | 埠號 (字串,預設埠為空) |
location.pathname | /web/index.aspx | 路徑 (以 / 開頭) |
location.search | ?category=books&id=123 | 查詢字串 (含 ?) |
location.hash | #section2 | 片段識別碼 (含 #) |
new URL(location.href).searchParams.get('id') | "123" | 現代 URLSearchParams 解析查詢參數 |
實用操作
// 解析查詢參數 (現代寫法)
const params = new URLSearchParams(window.location.search);
const category = params.get('category'); // "books"
const id = params.get('id'); // "123"
// 建立新 URL
const newUrl = new URL('/api/books', window.location.origin);
newUrl.searchParams.set('category', category);
fetch(newUrl).then(...)
// 重導向
window.location.href = '/login?returnUrl=' + encodeURIComponent(window.location.pathname + window.location.search);
window.location.assign(url); // 同 href 但可攔截
window.location.replace(url); // 替換歷史記錄 (無法返回)
// 重新整理
window.location.reload(); // 從伺服器重載
window.location.reload(true); // 強制略過快取
跨端傳遞 URL 資訊最佳實踐
1. 伺服端渲染注入給前端
<script>
// Razor / Web Forms
window.appConfig = {
baseUrl: "@Request.Url.GetLeftPart(UriPartial.Authority)@Request.ApplicationPath",
currentPath: "@Request.RawUrl",
isDebug: @(HttpContext.Current.IsDebuggingEnabled.ToString().ToLower())
};
</script>
2. AJAX 請求自動帶入相對路徑
// jQuery
$.ajax({
url: '/api/users', // 相對路徑自動解析為當前源
// 或明確指定
url: window.appConfig.baseUrl + '/api/users'
});
// Axios 全域基礎路徑
axios.defaults.baseURL = window.appConfig.baseUrl + '/api';
常見陷阱
| 情境 | 錯誤預期 | 正確理解 |
| 取得 #fragment 內容 | 伺服端 Request.Url.Fragment 有值 | **瀏覽器從不傳送 fragment 給伺服器**,伺服端永遠拿不到 |
| 反向 Proxy 後取得真實 IP/Host | Request.Url.Host 為內網 IP | 需讀取 X-Forwarded-Host, X-Forwarded-Proto 標頭,或設定 ForwardedHeadersMiddleware (Core) |
| JavaScript location.href 設定相對路徑 | location.href = "page2.aspx" 相對當前目錄 | 相對路徑解析基準為 location.pathname 的目錄,建議用 new URL('page2.aspx', location.origin) |
| ASP.NET Core Request.Path 包含查詢字串 | 以為 Path 包含 ?query | Request.Path 僅路徑,查詢字串在 Request.QueryString |