使用者位置

在使用者授予同意後,您就能透過 Geolocation API 找出使用者的位置。

Geolocation API 可讓您在使用者同意的情況下,取得使用者的位置資訊。這項功能可用於引導使用者前往目的地,以及為使用者建立的內容加上地理標記,例如標示相片的拍攝地點。

Geolocation API 還可讓您查看使用者的位置,並在使用者移動時追蹤他們,但前提是必須取得使用者的同意 (且僅限網頁開啟時)。這會產生許多有趣的用途,例如與後端系統整合,在使用者靠近時準備訂單。

使用 Geolocation API 時,請務必留意許多事項。本指南將說明常見用途和解決方案。

摘要

  • 在對使用者有利的情況下使用地理位置。
  • 在使用者手勢後,明確要求權限。
  • 如果使用者的瀏覽器不支援地理位置,請使用功能偵測。
  • 除了瞭解如何導入地理位置功能,也應學習最佳做法。
  • 測試網站的地理位置。

地理位置的使用時機

  • 找出使用者最接近的特定實體位置,量身打造使用者體驗。
  • 根據使用者所在位置提供合適的資訊 (例如新聞)。
  • 在地圖上顯示使用者的位置。
  • 使用使用者的位置資訊,標記在應用程式中建立的資料 (也就是為相片加上地理標記)。

以負責任的態度要求權限

最近的使用者研究顯示,如果網站只是在載入網頁時提示使用者提供位置資訊,使用者會不信任該網站。那麼,最佳做法有哪些?

假設使用者不會提供位置資訊

許多使用者不願意提供位置資訊,因此您需要採用防禦性開發風格。

  1. 處理 Geolocation API 以外的所有錯誤,以便根據這種情況調整網站。
  2. 清楚明確地說明您需要位置資訊的原因。
  3. 必要時請使用備用解決方案。

如果需要地理位置,請使用備用方案

建議您的網站或應用程式不要要求存取使用者的目前位置。不過,如果您的網站或應用程式需要使用者的目前位置,可以透過第三方解決方案,取得使用者目前位置的最佳推測。

這類解決方案通常會查看使用者的 IP 位址,並對應至 RIPE 資料庫中註冊的實體地址。這些位置通常不太準確,一般會提供距離使用者最近的電信中心或手機基地台位置。在許多情況下,這些資訊甚至可能不準確,尤其是使用者使用 VPN 或其他 Proxy 服務時。

一律在使用者手勢時要求位置存取權

請務必讓使用者瞭解您要求位置資訊的原因,以及這對他們有何好處。如果網站在載入時立即在首頁要求權限,會導致使用者體驗不佳。

在商店搜尋工具頁面要求權限的網站。
建議做法:一律在使用者手勢上要求位置存取權。
在首頁要求權限的網站。
不建議:在網站載入時,於首頁要求權限,這會導致使用者體驗不佳。

請改為向使用者提供明確的行動號召,或指出某項作業需要存取其位置資訊。這樣一來,使用者就能更輕鬆地將系統提示與剛啟動的操作建立關聯。

清楚指出某項動作會要求提供位置資訊

在 Google Ads 團隊的一項研究中,當使用者被要求在某個飯店網站上預訂波士頓的飯店房間,以便參加即將舉行的會議時,系統會在使用者輕觸首頁上的「尋找並預訂」行動號召後,立即提示使用者分享 GPS 位置。

在某些情況下,使用者會感到不滿,因為他們不明白為什麼想預訂波士頓的房間,卻看到舊金山的飯店。

為提供更優質的體驗,請務必讓使用者瞭解您要求提供位置資訊的原因。新增跨裝置通用的知名符號,例如測距儀,或明確的行動號召,例如「尋找附近」。

測距儀。
使用範圍搜尋工具
含有「尋找附近」按鈕的表單。
明確的行動號召,引導使用者尋找附近地點

溫和提醒使用者授予位置資訊存取權

您無法存取使用者正在執行的任何操作。您確切知道使用者何時不允許存取位置,但不知道他們何時授予存取權,只有在結果顯示時,您才知道已取得存取權。

如果需要使用者完成動作,建議您「輕推」使用者採取行動。

排練期間,建議採用以下做法:

  1. 設定計時器,在短時間後觸發;5 秒是合適的值。
  2. 如果收到錯誤訊息,請向使用者顯示訊息。
  3. 如果收到正面回應,請停用計時器並處理結果。
  4. 如果逾時後仍未收到正面回應,請向使用者顯示通知。
  5. 如果回應稍後才傳入,且通知仍顯示在畫面上,請將其移除。
button.onclick = function () {
  var startPos;
  var nudge = document.getElementById('nudge');

  var showNudgeBanner = function () {
    nudge.style.display = 'block';
  };

  var hideNudgeBanner = function () {
    nudge.style.display = 'none';
  };

  var nudgeTimeoutId = setTimeout(showNudgeBanner, 5000);

  var geoSuccess = function (position) {
    hideNudgeBanner();
    // We have the location, don't display banner
    clearTimeout(nudgeTimeoutId);

    // Do magic with location
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
  };
  var geoError = function (error) {
    switch (error.code) {
      case error.TIMEOUT:
        // The user didn't accept the callout
        showNudgeBanner();
        break;
    }
  };

  navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
};

瀏覽器支援

目前大多數瀏覽器都支援 Geolocation API,但建議您在執行任何操作前,一律先檢查是否支援。

您可以測試地理位置物件是否存在,輕鬆檢查相容性:

// check for Geolocation support
if (navigator.geolocation) {
  console.log('Geolocation is supported!');
} else {
  console.log('Geolocation is not supported for this Browser/OS.');
}

判斷使用者目前的位置

Geolocation API 提供簡單的「一次性」方法,可取得使用者的位置:getCurrentPosition()。呼叫這個方法會以非同步方式回報使用者目前的位置。

window.onload = function () {
  var startPos;
  var geoSuccess = function (position) {
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
  };
  navigator.geolocation.getCurrentPosition(geoSuccess);
};

如果這是該網域上的應用程式首次要求權限,瀏覽器通常會檢查使用者是否同意。視瀏覽器而定,可能也會有偏好設定,一律允許或不允許權限查詢,在這種情況下,系統會略過確認程序。

視瀏覽器使用的定位裝置而定,位置物件實際包含的資訊可能不只有經緯度,例如可能包含海拔高度或方向。在定位系統實際傳回資料之前,您無法得知該系統使用了哪些額外資訊。

監控使用者位置

Geolocation API 可讓您在使用者同意的情況下,透過單一 getCurrentPosition() 呼叫取得使用者位置。

如要持續監控使用者的位置,請使用 Geolocation API 方法 watchPosition()。運作方式與 getCurrentPosition() 類似,但定位軟體會多次觸發:

  1. 更準確地鎖定使用者。
  2. 判斷使用者的位置是否正在變更。
var watchId = navigator.geolocation.watchPosition(function (position) {
  document.getElementById('currentLat').innerHTML = position.coords.latitude;
  document.getElementById('currentLon').innerHTML = position.coords.longitude;
});

何時應使用地理位置功能監控使用者位置

  • 您想更精確地鎖定使用者位置。
  • 應用程式需要根據新的位置資訊更新使用者介面。
  • 當使用者進入特定定義區域時,應用程式需要更新商業邏輯。

使用地理位置的最佳做法

隨時清理並節省電池用量

監控地理位置變更並非免費作業。雖然作業系統可能會推出平台功能,讓應用程式連結至地理子系統,但身為網頁程式開發人員,您無法得知使用者的裝置支援哪些位置監控功能,而且在監控位置時,裝置會進行大量額外處理。

不再需要追蹤使用者位置時,請呼叫 clearWatch 關閉地理定位系統。

明確解釋錯誤原因

不過,並非所有位置查詢都能成功。例如無法定位 GPS,或使用者突然停用位置查詢功能。如果發生錯誤,系統會呼叫 getCurrentPosition() 的第二個選用引數,以便您在回呼中通知使用者:

window.onload = function () {
  var startPos;
  var geoSuccess = function (position) {
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
  };
  var geoError = function (error) {
    console.log('Error occurred. Error code: ' + error.code);
    // error.code can be:
    //   0: unknown error
    //   1: permission denied
    //   2: position unavailable (error response from location provider)
    //   3: timed out
  };
  navigator.geolocation.getCurrentPosition(geoSuccess, geoError);
};

減少啟動地理定位硬體的需求

在許多用途中,您不需要使用者的最新位置,只需要概略估算。

使用 maximumAge 選用屬性,指示瀏覽器使用最近取得的地理位置結果。如果使用者先前曾要求提供資料,這樣做不僅能更快傳回資料,還能防止瀏覽器啟動地理位置硬體介面,例如 Wi-Fi 三角定位或 GPS。

window.onload = function () {
  var startPos;
  var geoOptions = {
    maximumAge: 5 * 60 * 1000,
  };

  var geoSuccess = function (position) {
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
  };
  var geoError = function (error) {
    console.log('Error occurred. Error code: ' + error.code);
    // error.code can be:
    //   0: unknown error
    //   1: permission denied
    //   2: position unavailable (error response from location provider)
    //   3: timed out
  };

  navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};

設定逾時,避免使用者等待

除非您設定逾時,否則目前位置的要求可能永遠不會傳回。

window.onload = function () {
  var startPos;
  var geoOptions = {
    timeout: 10 * 1000,
  };

  var geoSuccess = function (position) {
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
  };
  var geoError = function (error) {
    console.log('Error occurred. Error code: ' + error.code);
    // error.code can be:
    //   0: unknown error
    //   1: permission denied
    //   2: position unavailable (error response from location provider)
    //   3: timed out
  };

  navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};

偏好大概位置,而非精確位置

舉例來說,如果想找出距離使用者最近的商店,就不太需要精確到 1 公尺。這個 API 旨在提供大概位置,並盡快傳回結果。

如果確實需要高精確度,可以使用 enableHighAccuracy 選項覆寫預設設定。請謹慎使用這項功能,因為解析速度較慢,且耗電量較大。

window.onload = function () {
  var startPos;
  var geoOptions = {
    enableHighAccuracy: true,
  };

  var geoSuccess = function (position) {
    startPos = position;
    document.getElementById('startLat').innerHTML = startPos.coords.latitude;
    document.getElementById('startLon').innerHTML = startPos.coords.longitude;
  };
  var geoError = function (error) {
    console.log('Error occurred. Error code: ' + error.code);
    // error.code can be:
    //   0: unknown error
    //   1: permission denied
    //   2: position unavailable (error response from location provider)
    //   3: timed out
  };

  navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
};

使用 Chrome 開發人員工具模擬地理位置

開發人員工具中的「感應器」分頁。

設定地理位置後,請執行下列操作:

  • 測試應用程式在不同地理位置的運作情形。
  • 確認應用程式在無法取得地理位置時,能正常降級。

這兩項操作都可以在 Chrome 開發人員工具中完成。

  1. 開啟 Chrome 開發人員工具。
  2. 按下 Esc 鍵,開啟控制台導覽匣。
  3. 開啟「Console」導覽匣選單
  4. 按一下「Sensors」選項,顯示「Sensors」分頁。

您可以在這裡將位置覆寫為預設的主要城市、輸入自訂位置,或將覆寫設定設為「Location unavailable」,停用地理定位功能。

意見回饋