MUKI AI Summary
Geolocation API 是 HTML5 Web API 中一個強大的工具,允許網頁存取使用者的地理位置,能提供導航、在地服務等功能。此 API 注重隱私,只有在使用者授權的前提下才能取得位置資訊。Geolocation API 的核心功能包括取得使用者目前位置、持續監控位置變化及提供位置精準度資訊。瀏覽器可透過 GPS、網路位置及 IP 位址來確定使用者位置。
使用 Geolocation API 前需檢查瀏覽器支援性,並透過 `getCurrentPosition()` 方法取得當前位置。此方法接受三個參數:成功回調、錯誤回調及選項設定。為了即時追蹤位置變化,可使用 `watchPosition()` 方法,並結合地圖服務如 OpenStreetMap 來顯示位置。若使用者拒絕授權,需引導其修改瀏覽器設定以重新啟用地理位置功能。此 API 提供的功能強大且安全,但需經過使用者同意以保護隱私。...
Geolocation API 是 HTML5 Web API 中非常強大的工具。它能讓網頁存取使用者裝置的地理位置,也因此能提供許多貼心的服務,例如導航位置、觀看在地天氣或是取得當地的服務 ... 等等。同時,Geolocation API 也是個注重隱私的 API,只有在使用者清楚授權並同意的前提下,我們才能取得使用者的地理位置,這使得 Geolocation API 成為一個強大好用,又兼具安全性的工具。
Geolocation API 的核心功能
Geolocation API 主要提供以下功能:
- 取得使用者目前的位置
- 持續監控使用者位置的變化
- 提供位置的精準度資訊
而瀏覽器可以通過以下方式,來確定使用者的地理位置:
- GPS 全球定位系統:精確且可靠,但耗電
- 網路位置 (如 Wi-Fi 或基地台定位):適合室內環境
- IP 位址定位:雖然不夠準確,但作為備選方案也夠用
檢查瀏覽器是否支援 Geolocation API
▼ 開始之前,我們通常會檢查瀏覽器是否支援這個 API,判斷方式如下
if ("geolocation" in navigator) { console.log("瀏覽器支援 Geolocation API"); } else { console.log("瀏覽器不支援 Geolocation API"); }
如果支援,就用 getCurrentPosition()
取得目前的位置
使用 getCurrentPosition()
取得當前位置
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
getCurrentPosition()
方法接受三個參數:
successCallback
:成功取得位置時執行的函數errorCallback
:取得位置失敗時執行的函數(選填)options
:相關的設定,如是否使用 HighAccuracy、設定 timeout ... 等等(選填)
▼ 完整範例
function successCallback(position) { const { latitude, longitude } = position.coords; console.log(`目前位置:緯度 ${latitude}, 經度 ${longitude}`); } function errorCallback(error) { console.error(`錯誤:${error.message}`); } const options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0, }; navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options);
options 參數說明
使用 Geolocation API 時,可以透過 options
物件來設定相關的選項,以下列舉 3 個選項,簡單介紹其含義與接受的值。
參數名稱 | 值的類型 | 預設值 | |
---|---|---|---|
enableHighAccuracy | Boolean | false | |
說明 | 設為 true 可以讓裝置提供更精準的位置,但相對的也會讓處理時間變長、需要更多的電量,或是增加消耗 GPS 晶片。 | ||
timeout | 正整數 | Infinity (單位:毫秒) | |
說明 | 取得使用者地理位置時,超過這個時間就會停止解析。如果有在 errorCallback 顯示 error,會看到錯誤為 Timer expired | ||
maximumAge | 正整數 | 0 (單位:毫秒) | |
說明 | 預設為 0 表示不進行快取,每次都要重新取得最新的使用者地理位置; 假如設定為 60000,表示允許使用過去 60 秒內取得的地理位置。 |
出現錯誤訊息:Only request geolocation information in response to a user gesture.
前面有提過,Geolocation API 必須要經過使用者的同意才能取得地理位置。因此這個錯誤表示我們在沒有經過使用者允許的情況下,就使用 Geolocation API 取得使用者的地理位置。
怎樣才算是取得使用者的同意呢?
▼ 我們要讓使用者進行明確的動作 (例如點選按鈕、點選連結) 後再要求 Geolocation 的權限。
if ("geolocation" in navigator) { console.log('瀏覽器支援 Geolocation'); // NOTE: 點選按鈕才會呼叫 getCurrentPosition() document.getElementById('geolocation').addEventListener('click', function () { function successCallback(position) { const latitude = position.coords.latitude; const longitude = position.coords.longitude; console.log(`緯度:${latitude},經度:${longitude}`); } function errorCallback(error) { console.error(`錯誤:${error.message}`); } const options = { enableHighAccuracy: true, timeout: 5000, maximumAge: 0 }; navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options); }); } else { console.log('瀏覽器不支援 Geolocation'); }
▼ 可以在 console 面板看到輸出的資訊
瀏覽器支援 Geolocation 緯度:15.0232011,經度:211.2709354
更好的顯示錯誤訊息
取得地理位置時可能會遇到各種問題,例如使用者拒絕授權,該裝置讀不到位置(本身不支援地理位置的功能),沒有網路或訊號不好… 等等
▼ 我們可以在 errorCallback
函數中,根據錯誤訊息顯示對應的文字
function errorCallback(error) { switch(error.code) { case error.PERMISSION_DENIED: console.error("使用者拒絕了地理位置請求。"); break; case error.POSITION_UNAVAILABLE: console.error("無法取得地理位置"); break; case error.TIMEOUT: console.error("請求超時。"); break; case error.UNKNOWN_ERROR: console.error("發生未知錯誤。"); break; } }
拒絕權限後該如何重新啟用
如果使用者一開始就拒絕分享地理位置,我們便無法使用 Geolocation API 取得地理位置,也無法再使用 JavaScript 重新觸發請求的對話框
但我們可以引導使用者,讓他們修改瀏覽器設定分享地理位置。以 Chrome 為例,選擇網址左側的 icon,再選擇「位置」 → 「重設權限」,然後重新載入頁面,就會跳出請求的對話框了
即時追蹤位置變化
Geolocation API 除了能取得使用者當前的地理位置外,還能監控地理位置的變化,通常用於導航類的 APP
▼ 使用 watchPosition()
方法來監控變化
const watchId = navigator.geolocation.watchPosition(successCallback, errorCallback, options);
▼ 該方法會返回一個 watchId
,我們可以用它來停止監控
navigator.geolocation.clearWatch(watchId);
結合地圖與模擬移動
Geolocation API 本身不提供地圖功能,因此我們會將取得的位置資訊與第三方地圖服務結合使用,常見的就是 Google Maps 或 OpenStreetMap。
▼ 鑒於 Googel Mpas 的設定較為繁瑣,我們就用 OpenStreetMap 和 Leaflet 來做一個追蹤位置變化的地圖功能吧
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" /> <script> let map; let marker; function initMap(lat, lon) { map = L.map('map').setView([lat, lon], 13); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map); marker = L.marker([lat, lon]).addTo(map); } if ("geolocation" in navigator) { console.log('瀏覽器支援 Geolocation'); document.getElementById('geolocation').addEventListener('click', function () { function successCallback(position) { const latitude = position.coords.latitude; const longitude = position.coords.longitude; initMap(latitude, longitude); console.log(`緯度:${latitude},經度:${longitude}`); } function errorCallback(error) { console.error(`錯誤:${error.message}`); } navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options); }); } else { console.log('瀏覽器不支援 Geolocation'); } </script>
▼ 按下 Get Location 按鈕,就會在地圖上顯示自己的所在位置
使用 watchPosition() 追蹤使用者的地理位置
▼ 再放三個按鈕,分別是追蹤與模擬移動的功能
原本是按下「Get Location」按鈕才會顯示位置,現在改成按下開始追蹤(startTracking()
),才會在地圖上顯示位置。
<div id="map"></div> <!-- status 顯示當前經緯度 --> <div id="status"></div> <!-- 加入三個按鈕 --> <div> <button onclick="startTracking()">開始追蹤</button> <button onclick="stopTracking()">停止追蹤</button> <button onclick="simulateMovement()">模擬移動</button> </div>
▼ 用 watchPosition()
取代 getCurrentPosition()
,用 watchPosition()
的 successCallback
將經緯度傳入 initMap()
// watchPosition 的 successCallback function updatePosition(position) { const { latitude, longitude } = position.coords; if (!map) { initMap(latitude, longitude); } else { map.setView([latitude, longitude], 13); marker.setLatLng([latitude, longitude]); } document.getElementById('status').textContent = `緯度: ${latitude}, 經度: ${longitude}`; } // watchPosition 的 errorCallback function handleError(error) { document.getElementById('status').textContent = `錯誤: ${error.message}`; } function startTracking() { if ("geolocation" in navigator) { watchId = navigator.geolocation.watchPosition(updatePosition, handleError); document.getElementById('status').textContent = "正在追蹤位置..."; } else { document.getElementById('status').textContent = "您的瀏覽器不支援地理位置功能。"; } }
模擬移動功能
▼ 開發中沒有真的串接使用者地理位置,所以寫了一個模擬移動的功能,可以隨機修改經緯度來模擬裝置的移動
function simulateMovement() { if (simulationInterval) { clearInterval(simulationInterval); simulationInterval = null; document.getElementById('status').textContent = "模擬移動已停止。"; } else { let lat = 48.860611; // 起始緯度 let lon = 2.3327785; // 起始經度 simulationInterval = setInterval(() => { lat += (Math.random() - 0.5) * 0.001; lon += (Math.random() - 0.5) * 0.001; updatePosition({ coords: { latitude: lat, longitude: lon } }); }, 1000); document.getElementById('status').textContent = "正在模擬移動..."; } }
範例程式碼
線上範例網址:https://mukiwu.github.io/web-api-demo/geo.html
請先點選「開始追蹤」並允許瀏覽器取得你的地理位置。
小結
Geolocation API 是 HTML5 Web API 中的一個強大功能,允許網頁存取使用者裝置的地理位置,但需要經過使用者的同意以保護隱私,建議大家在取得使用者的地理位置前,應清楚解釋需求,並能提供如何修改瀏覽器設定,以便重新授權地理位置存取,避免日後爭議。
以上就是 Geolocation API 的介紹,有任何問題歡迎留言討論唷。