浏览器 API 之地理位置

2017-02-18 18:18 #旧文章

本文翻译自 MDN,原文版本为 Jan 28, 2017, 9:36:29 PM

地理位置 API 允许用户向网页应用提供位置信息。为了保护隐私,使用这个 API 需要向用户申请权限。

位置对象

地理位置 API 可以通过 navigator.geolocation 对象调用。

如果这一个对象存在,则地理位置服务可用。你可以这样来测试地理位置服务的可用性:

if ("geolocation" in navigator) {
/* 位置服务可用 */
} else {
/* 位置服务不可用 */
}

警告

在 Firefox 24 及以下版本中,"geolocation" in navigator 永远为 true,无论这一 API 是否被禁用。这在 Firefox 25 中被修复。(bug 884921)

获取当前位置

你可以通过调用 getCurrentPosition()方法来获取用户当前的位置。这个方法初始化了一个异步的请求来侦测用户的位置,然后定位硬件开始获取实时信息。当位置确定后,给出的回调函数会被执行。你可以选择性地提供第二个回调函数,这个函数会在定位错误时被执行。你可以通过第三个参数(可选的)来指定等待定位的最长时间,同时也能指定你想要的定位精度。

提示

默认地,getCurrentPosition()会尽量在最短的时间内返回一个低精度的数据。例如,带有 GPS 的设备,可能会花费数分钟来获得准确定位,这样低精度的网络位置也许会先被返回。

navigator.geolocation.getCurrentPosition(function (position) {
do_something(position.coords.latitude, position.coords.longitude);
});

上面的示例会在有数据返回时调用 do_something()函数。

监听实时位置

如果位置信息改变了(由与设备移动或有更高精度的信息返回),你可以提供一个更新位置信息的回调函数给 watchPosition(),其参数和 getCurrentPosition()相同。该回调函数会被多次调用,这使得浏览器能够通知网页应用位置改变了。可选的错误回调函数也可能会被多次调用。

提示

你可以在未调用 getCurrentPosition()的情况下调用 watchPosition()

var watchID = navigator.geolocation.watchPosition(function (position) {
do_something(position.coords.latitude, position.coords.longitude);
});

watchPosition()方法返回一个 ID,这个 ID 可以用于唯一地指定一个位置监听器,你可以通过调用 clearWatch()方法来停止监听。

navigator.geolocation.clearWatch(watchID);

正确的使用方法

getCurrentPosition()watchPosition()的第一个参数都是成功回调函数,第二个是可选的错误回调函数,第三个是可选的 PositionOptions 对象。

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,
);

另一个使用例子

位置的描述

用户的位置通过一个位置对象中的坐标对象来描述。

错误处理

如果提供了错误回调函数,那么回调函数的第一个参数会是一个 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);
}

运行结果

由于我的网站设置的 CSP 禁止了动态的 JavaScript 加载,所以暂时不能在这里展示。
有关 CSP 的介绍看这里

请到原文中查看运行效果。

兼容性

桌面系统特性ChromeFirefox (Gecko)IEOperaSafari
基础支持5.03.5 (1.9.1)1910.60 不支持 15.0 16.05
Secure origins only50.0不支持不支持3910
手机系统特性AndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
基础支持?(Yes)4.0 (4)1.0.1?10.60 不支持 15.0 16.03.2(Yes)
Secure origins only?50.010.150.0
  1. Firefox 使用了谷歌的位置服务(基于你的 WiFi 信息)。在 Firefox 和 Google 之间的数据交换中,WiFi 接入点的信息将与一个访问令牌和 IP 一起传送。更多的信息请查看 Mozilla 的隐私策略及 Google 的隐私策略(包含了这些信息将被如何使用)。
    Firefox 3.6 (Gecko 1.9.2)为 Linux 加入了基于 GPSD(GPS daemon)的支持。

参考资料