使用者位置

Geolocation API 可讓您在取得使用者同意的情況下,探索使用者的位置。

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

此外,Geolocation 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(),取得使用者的位置資訊 (須經使用者同意)。

如要持續監控使用者的位置,請使用 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. 開啟主控台導覽匣選單
  4. 按一下「Sensors」選項,顯示「Sensors」分頁標籤。

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

意見回饋: