HOWTO · JavaScript

如何在 JavaScript 中獲取客戶端 IP 地址

了解瀏覽器 JavaScript 如何使用 ipify、ipinfo 或 Abstract 擷取服務觀察到的公共 IP 地址。

本頁內容

瀏覽器 JavaScript 無法直接讀取裝置的公共 IP 地址。它可以向 IP 查詢服務傳送請求,該服務會報告它為該請求觀察到的公共地址。這與本機網路中使用的私人地址不同。該請求還會與第三方提供者共用訪客的 IP 地址,因此請選擇資料處理方式適合你的應用的服務。

下面的範例使用現代瀏覽器中可用的 fetch。它們涵蓋三個提供者:ipify 提供僅含 IP 的回應,ipinfo 提供 IP 和位置欄位,Abstract 提供地理位置資料。請根據你的應用需要的欄位、提供者是否需要憑證以及你將如何保護任何憑證來進行選擇。這些請求從訪客的瀏覽器執行,因此提供者會看到訪客的公共 IP。提供者的可用性、回應欄位和存取規則可能會變更;部署前請查閱提供者的最新文件。

使用 ipify 獲取公共 IP 地址

ipify 在 https://api.ipify.org?format=json 提供了一個 JSON 端點。回應包含一個 ip 屬性。此範例讀取該值並將其顯示出來。ipify API 倉庫 包含該專案的原始碼。

// Use a representative response so the parsing path is deterministic.
globalThis.fetch = async () => ({
  ok: true,
  json: async () => ({ ip: '203.0.113.42' }),
});

(async () => {
  try {
    const response = await fetch('https://api.ipify.org?format=json');
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    const data = await response.json();
    console.log(data.ip);
  } catch (error) {
    console.log('Could not retrieve the public IP:', error.message);
  }
})();
203.0.113.42

該請求在解析 JSON 之前檢查 HTTP 狀態,然後讀取 ip 欄位。如果失敗,請檢查瀏覽器的網路面板,了解連線、服務或內容安全原則方面的詳細資訊。此方法返回 ipify 觀察到的地址;它不會洩露裝置的私人 LAN 地址。當僅含 IP 的回應就足夠且不需要額外的位置欄位時,請使用此方法。

使用 ipinfo 獲取 IP 和位置資料

ipinfo 返回一個 ip 欄位,並可能提供與位置相關的欄位,例如 city、region、country 和 loc。該範例使用一個代表性回應來展示如何讀取這些欄位;其本機 fetch 替代使示範不依賴於網路存取。對於實際請求,請使用下面所示的 JSON 端點。可用欄位和存取可能取決於請求和提供者的目前要求,因此請查閱提供者關於憑證和方案限制的文件,而不要依賴固定的配額數字。

// Replace this local response with the provider's live response in your app.
globalThis.fetch = async () => ({
  ok: true,
  json: async () => ({
    ip: '203.0.113.42',
    city: 'Austin',
    region: 'Texas',
    country: 'US',
    loc: '30.2672,-97.7431',
  }),
});

(async () => {
  try {
    const response = await fetch('https://ipinfo.io/json');
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    const data = await response.json();
    console.log('IP:', data.ip);
    console.log('Location:', data.city, data.region, data.country);
  } catch (error) {
    console.log('Could not retrieve IP information:', error.message);
  }
})();
IP: 203.0.113.42
Location: Austin Texas US

當你只需要觀察到的地址時,請使用 ip 欄位。附加欄位可以支援廣泛的區域顯示,但位置資料是近似的,並且取決於提供者的資料;它不能確定裝置的精確位置。如果請求失敗,請檢查網路回應以及端點的目前存取要求是否適用於你的使用情況。

使用 Abstract 獲取 IP 和地理位置資料

Abstract 提供了一個 IP 地理位置端點。其請求使用 API 金鑰,因此請透過提供者建立一個金鑰,並替換下面的預留位置。URL API 將金鑰編碼為查詢參數。此範例使用一個代表性回應,並列印其 IP 和位置欄位;本機 fetch 替代使解析範例具有確定性。對於實際請求,在為你的介面選擇欄位之前,請查閱提供者關於帳戶存取、配額和回應架構的最新文件。嵌入瀏覽器 JavaScript 中的金鑰對訪客可見;如果金鑰必須保持私密,請使用伺服器端代理。

// Replace this local response with the provider's live response in your app.
globalThis.fetch = async () => ({
  ok: true,
  json: async () => ({
    ip_address: '203.0.113.42',
    city: 'Austin',
    region: 'Texas',
    country: 'United States',
    latitude: 30.2672,
    longitude: -97.7431,
  }),
});

(async () => {
  const apiKey = 'YOUR_ABSTRACT_API_KEY';
  const url = new URL('https://ipgeolocation.abstractapi.com/v1/');
  url.searchParams.set('api_key', apiKey);

  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    const data = await response.json();
    console.log('IP:', data.ip_address);
    console.log('Location:', data.city, data.region, data.country);
    console.log('Coordinates:', data.latitude, data.longitude);
  } catch (error) {
    console.log('Could not retrieve geolocation data:', error.message);
  }
})();
IP: 203.0.113.42
Location: Austin Texas United States
Coordinates: 30.2672 -97.7431

該範例從返回的物件中讀取 IP 和位置欄位。本機樣本僅示範解析;它不驗證實際的服務回應。缺失、被拒絕或受限制的 API 金鑰可能導致錯誤回應;網路和服務故障也可能阻止獲得結果。請在應用中處理這些情況,並在調整範例以顯示特定欄位時檢查回應和提供者文件。當 Abstract 目前的回應和存取條款適合你的應用所需的位置資料時,請選擇 Abstract。