紀錄工作經驗、相關知識,解決技術相關問題。

Javascript

JavaScript location.host 用法教學:取得網域與連接埠號、預設 Port 省略規則與 hostname 差異

JavaScript location.host 與 hostname 差異與網址參數取得範例 特色圖片

在 JavaScript 前端開發中,若需要同時取得當前頁面的「網域名稱與連接埠號(Host:Port)」,標準做法是存取 window.location.host 屬性。與僅回傳純網域名稱的 location.hostname 不同,location.host 在網址帶有非預設連接埠(例如 :8080 或 :3000)時會完整保留埠號資訊,是動態組裝同主機服務網址與 WebSocket 連線的關鍵屬性。

⚡ 快速跳轉(依實務情境選擇):

基本語法:取得網域與連接埠號(Host:Port)

假設當前網址為(帶有非預設連接埠 :8080):

https://www.seanacnet.com:8080/js/location-host.html?id=111&t=9#template

使用範例:

// 1. 取得 host(包含網域名稱與非預設連接埠號)
const host = window.location.host;
console.log(host);
// 輸出: "www.seanacnet.com:8080"

// 2. 對比:若只需要純網域名稱(不含 :8080),請改用 location.hostname
const hostname = window.location.hostname;
console.log(hostname);
// 輸出: "www.seanacnet.com"

// 3. 對比:若只需要單獨取得連接埠號,請使用 location.port
const port = window.location.port;
console.log(port);
// 輸出: "8080"

關鍵避坑:為什麼 HTTP 80 與 HTTPS 443 的連接埠號會消失?

許多工程師在測試 location.host 時常遇到一個疑問:「為什麼有時候 location.host 有包含 :port,有時候卻跟 location.hostname 完全一樣沒有連接埠號?」

根據 WHATWG URL Standard 規範,瀏覽器在序列化 location.host 時,會自動檢查連接埠是否為該傳輸協定(Protocol)的預設連接埠(Default Port):

  • HTTP 預設連接埠為 80:若網址為 http://www.seanacnet.com 或明確寫出 http://www.seanacnet.com:80,瀏覽器皆會自動省略 :80,此時 location.host 只會回傳 "www.seanacnet.com"。
  • HTTPS 預設連接埠為 443:若網址為 https://www.seanacnet.com 或 https://www.seanacnet.com:443,瀏覽器會自動省略 :443,回傳 "www.seanacnet.com"。
  • 非預設連接埠(如 :3000、:8080,或在 https:// 後方掛 :80):只要連接埠與協定預設值不符,location.host 就會完整回傳 "網域名稱:連接埠號"。
當前瀏覽器網址 (URL)協定預設埠location.host 輸出結果location.port 輸出結果
https://www.seanacnet.com/path443"www.seanacnet.com"""(空字串)
https://www.seanacnet.com:443/path443"www.seanacnet.com"""(自動省略)
http://www.seanacnet.com:80/path80"www.seanacnet.com"""(自動省略)
http://localhost:3000/path80"localhost:3000""3000"
https://www.seanacnet.com:8080/path443"www.seanacnet.com:8080""8080"

實務場景:動態組裝 WebSocket 與同源服務連線網址

既然判斷網域通常建議用 location.hostname,那麼在什麼實務場景下非用 location.host 不可?

答案是:當前端需要動態連接與當前頁面「同主機、同連接埠」的 WebSocket 或後端 Proxy 服務時。

在本地開發環境(例如 http://localhost:5173 或 http://localhost:3000)中,開發伺服器通常透過非預設連接埠轉發 WebSocket 連線。若誤用 location.hostname,組裝出的網址會漏掉 :5173 而連往預設的 80 埠導致連線失敗;使用 location.host 則能同時相容本地開發(保留 :5173)與正式環境(自動省略 :443):

function createSameHostWebSocket(path = '/ws') {
  // 根據當前頁面協定 (https: 或 http:) 自動切換 wss:// 或 ws://
  const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';

  // 關鍵:必須使用 location.host,確保在 localhost:3000 開發時不會漏掉 :3000
  const wsUrl = `${wsProtocol}//${window.location.host}${path}`;

  return new WebSocket(wsUrl);
}

// 於 http://localhost:3000 執行時連線至: "ws://localhost:3000/ws"
// 於 https://www.seanacnet.com 執行時連線至: "wss://www.seanacnet.com/ws"

若您在本地開發串接 API 時遇到跨來源連線阻擋,也可參考站內教學:如何使用 Chrome 套件解決 Localhost 開發中的 CORS 問題。

location.host 與 location.hostname 差異比較表

比較項目location.host(本篇主角)location.hostname
回傳內容格式網域名稱:非預設連接埠號僅 純網域名稱(永遠不含連接埠)
localhost:3000 下回傳值"localhost:3000""localhost"
最佳適用場景動態建立 WebSocket 網址、組裝含連接埠之本地開發回呼網址判斷 localhost 環境、拆解子網域(Subdomain)、設定 Cookie 網域
修改賦值行為可同時變更網域與連接埠(如 location.host = "localhost:8080")僅變更網域名稱(若原網址有非預設連接埠會被保留)

若您需要進一步解析 URL 中的其他參數(如純網域名稱、連接埠、查詢字串或路徑),請參考以下站內文章:

參考資料

發表迴響