使用者位置

使用者同意後,您就能透過 Geolocation API 查看使用者的位置。

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

您也可以使用地理位置 API 查看使用者所在位置,並在使用者移動時持續追蹤他們,但必須取得使用者同意 (且僅限於網頁開啟時)。這會產生許多有趣的用途,例如在使用者附近時,整合後端系統以準備取貨訂單。

使用 Geolocation API 時,您需要注意許多事項。本指南將逐步說明常見的用途和解決方案。

摘要

  • 對使用者有利的情況下,使用地理位置功能。
  • 要求權限,以便對使用者手勢做出明確回應。
  • 在使用者瀏覽器不支援地理位置的情況下使用功能偵測功能。
  • 除了瞭解如何實作地理位置功能,也請瞭解使用地理位置功能的最佳方式。
  • 測試網站的地理位置。

地理位置的使用時機

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

以負責任的態度要求權限

近期的使用者研究顯示,如果網站在網頁載入時只提示使用者提供位置資訊,使用者就會對該網站產生不信任感。那麼,最佳做法為何?

假設使用者將不會為您提供其所在位置

許多使用者不願提供自己的所在位置,因此您必須採用防禦性開發風格。

  1. 處理地理位置 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(),取得使用者的位置資訊 (經使用者同意)。

如果您想持續監控使用者的所在位置,請使用地理定位 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. 開啟控制台導覽匣選單
  4. 按一下「Sensors」選項,顯示「Sensors」分頁。

您可在這裡將位置覆寫為預設的主要城市、輸入自訂位置,或是將覆寫值設為「Location not available」來停用地理位置。

意見回饋