Web Apps 若需要使用者的位置,可透過 Geolocation API 取得相關資訊。而基於隱私權的考量,這些 Web Apps 均必須取得使用者的許可之後,才能發佈位置資訊。
地理位置定位 (Geolocation) 物件
Geolocation API,是透過 navigator.geolocation
物件
所發佈。
若該物件可用,即可進行地理位置定位服務。因此可先測試地理位置定位是否存在:
if ("geolocation" in navigator) { /* geolocation is available */ } else { /* geolocation IS NOT available */ }
navigator
中的「geolocation」也同樣回傳
true。此問題已根據規格而於
Firefox 25 中修正 (bug 884921)。取得目前位置
若要取得使用者目前的位置,可呼叫 getCurrentPosition()
函式。如此將啟動非同步化的請求,以偵測使用者的位置,並將查詢定位硬體而取得最新資訊。一旦決定位置,隨即執行特定的回呼常式 (Callback routine)。若發生錯誤,則可選擇是否提供第二次回呼。第三項參數為選項介面 (亦可選擇是否使用之),可設定位置回傳的的最長時間,與請求的等待時間。
若不論定位精確度而想儘快固定單一位置,則可使用 getCurrentPosition()
。以具備 GPS 的裝置為例,往往需耗時 1 分鐘或更長的時間而固定 GPS 資訊。也因此,getCurrentPosition()
可能取得較低精確度的資料 (IP 位置或 WiFi) 而隨即開始作業。
注意:依預設值,getCurrentPosition()
將儘快回傳較低精確度的結果。若不論精確度而只要儘快獲得答案,則可使用 getCurrentPosition()
。舉例來說,搭載 GPS 的裝置可能需要一段時間才能取得 GPS 定位資訊,所以可能將低精確度的資料 (IP 位置或 Wifi) 回傳至 getCurrentPosition()
。
navigator.geolocation.getCurrentPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); });
一旦取得定位位置之後,上列範例隨即將執行 do_something()
函式。
觀看目前位置
如果定位資料改變 (可能是裝置移動,或取得更精確的地理位置資訊),則可設定 1 組回呼函式,使其隨著更新過的定位資訊而呼叫之。而這個動作可透過 watchPosition() 函式
完成。watchPosition()
所具備的輸入參數與 getCurrentPosition()
相同。回呼函式將呼叫數次,讓瀏覽器可於使用者移動期間更新位置,或可根據目前所使用的不同定位技術,提供更精確的定位資訊。若一直未回傳有效結果,則錯誤回呼 (Error Callback) 函式僅將呼叫 1 次。另請注意,錯誤回呼函式僅限於 getCurrentPosition(),因此為選填
。
注意:不需啟動 getCurrentPosition()
呼叫,亦可使用 watchPosition()
。
var watchID = navigator.geolocation.watchPosition(function(position) { do_something(position.coords.latitude, position.coords.longitude); } );
watchPosition()
函式將回傳 1 組 ID 編號,專用以識別必要的定位監看員 (Watcher)。而此數值若搭配 clearWatch()
函式,即可停止觀看使用者的位置。
navigator.geolocation.clearWatch(watchID);
微調回應
getCurrentPosition()
與 watchPosition()
均可容納 1 組成功回呼、1 組錯誤回呼 (選填)、1 組 PositionOptions
物件 (選填)。
對 watchPosition
的呼叫應類似如下:
function geo_success(position) { do_something(position.coords.latitude, position.coords.longitude); } function geo_error() { alert("Sorry, no position available."); } var geo_options = { enableHighAccuracy: true, maximumAge : 30000, timeout : 27000 }; var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
現成的 watchPosition Demo:https://www.thedotproduct.org/experiments/geo/
敘述位置
以 Position
物件參照 Coordinates
物件,即可敘述使用者的位置。
處理錯誤
在呼叫 getCurrentPosition()
或 watchPosition() 時,
若獲得錯誤回呼函式,則錯誤回呼函式的第一組參數將為 PositionError 物件:
function errorCallback(error
) { alert('ERROR(' +error
.code
+ '): ' +error
.message
);};
地理位置定位實際範例
HTML 內容
<p><button onclick="geoFindMe()">Show my location
</button></p>
<div id="out"></div>
JavaScript 內容
function geoFindMe() { var output = document.getElementById("out"); if (!navigator.geolocation){ output.innerHTML = "<p>Geolocation is not supported by your browser</p>"; return; } function success(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>'; var img = new Image(); img.src = "https://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=13&size=300x300&sensor=false"; output.appendChild(img); }; function error() { output.innerHTML = "Unable to retrieve your location"; }; output.innerHTML = "<p>Locating…</p>"; navigator.geolocation.getCurrentPosition(success, error); }
現場測試結果
若無法顯示,可至本文右上角「Language」切換回英文原文觀看。
請求權限
addons.mozilla.org 上所提供的任何附加元件,只要使用地理位置定位資料,均必須明確取得許可才能繼續作業。下列函式詢問許可的方法,則類似網頁詢問許可的自動提示方法,但更為簡單。若為可套用的狀態,則使用者的回應將儲存於 pref
參數所指定的偏好中。於 callback
參數中所提供的函式,將透過 1 組代表使用者反應的布林值而呼叫之。若使用者的回應為 true
,則附加元件才會存取地理位置定位資料。
function prompt(window, pref, message, callback) { let branch = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); if (branch.getPrefType(pref) === branch.PREF_STRING) { switch (branch.getCharPref(pref)) { case "always": return callback(true); case "never": return callback(false); } } let done = false; function remember(value, result) { return function() { done = true; branch.setCharPref(pref, value); callback(result); } } let self = window.PopupNotifications.show( window.gBrowser.selectedBrowser, "geolocation", message, "geo-notification-icon", { label: "Share Location", accessKey: "S", callback: function(notification) { done = true; callback(true); } }, [ { label: "Always Share", accessKey: "A", callback: remember("always", true) }, { label: "Never Share", accessKey: "N", callback: remember("never", false) } ], { eventCallback: function(event) { if (event === "dismissed") { if (!done) callback(false); done = true; window.PopupNotifications.remove(self); } }, persistWhileVisible: true }); } prompt(window, "extensions.foo-addon.allowGeolocation", "Foo Add-on wants to know your location.", function callback(allowed) { alert(allowed); });
瀏覽器相容性
瀏覽器 | 基本支援 | Geolocation Level 2 |
---|---|---|
Internet Explorer | IE9 RC | --- |
Firefox (Gecko) | 3.5 (1.9.1) | --- |
Opera | 10.60 | --- |
Safari | Chrome | WebKit | 5 | 5 | 533 | --- |
Gecko 註記
Firefox 可透過 Google 的定位服務 (Google Location Services,GLS),根據使用者的 WiFi 資訊而找出使用者的位置。與 Google 之間所交換的資料,包含 WiFi 存取點 (Access Point) 資料、Access token (類似 2 個禮拜的 cookie)、使用者的 IP 位址。若需更多資訊,可參閱 Mozilla 的隱私權政策與 Google 的隱私權政策。其內將詳述資料的使用方式。
Firefox 3.6 (Gecko 1.9.2) 新支援了 GPSD (GPS daemon) 服務,適合 Linux 的地理位置定位。