使用javascript获取网站访问者的地理位置

为了某种需求,有时候需要获取网站访问者的地理位置。现在有两种可选的方式:

使用地理位置 API
IP 地址查找
Geolocation API

地理位置API是HTML5的一个功能,允许向用户发送请求获取地理位置的提醒,如果用户同意,则可以获取用户地理位置。

显然,如果用户不同意,则不能获取用户的地理位置。

if ("geolocation" in navigator) {
  // 检查对当前的浏览器geolocation是支持/禁用
  navigator.geolocation.getCurrentPosition(
   function success(position) {
     // 当获取位置成功时运行此函数
     console.log('latitude', position.coords.latitude,
                 'longitude', position.coords.longitude);
   },
  function error(error_message) {
    // 当获取位置出现错误时运行此函数
    console.error('An error has occured while retrieving location', error_message)
  }
});
} else {
  // geolocation 不支持
  // 通过其他方式获取地理位置
  console.log('geolocation is not enabled on this browser')
}

缺点:这种方式只在使用https的网站上可以用。不支持IE10及以下,或者 OperaMini。
这种方式只能获取到地理坐标。如果我们想要获取实际对应的地理位置,我们就需要使用 IP 地址查找。

 IP 地址查找

IP地址查找包括:IP Geolocation APIIPinfo还有GEOIP DB。这些API提供的数据类型如:JSON, XML 还有 CSV。如果想获取关于这些API的更多知识,可以查看相关文档。
这里我们使用 IP Geolocation API,并且使用jQuery库。

function ipLookUp () {
  $.ajax('http://ip-api.com/json')
  .then(
      function success(response) {
          console.log('User's Location Data is ', response);
          console.log('User's Country', response.country);
      },

      function fail(data, status) {
          console.log('Request failed.  Returned status of',
                      status);
      }
  );
}
ipLookUp()

输出如下:

缺点:虽然总是可以精确获取IP地址所在国家,但是地理位置不总是精确地。还有,如果你请求的次数过多,可能需要为这些API付费。
你可以使用IP查找作为备选方案。当浏览器的地理位置API不支持获取地理位置的时候,或者出现错误的时候可以通过以下代码来弥补:

if ("geolocation" in navigator) {
  // 检查对当前的浏览器geolocation是支持/禁用
  navigator.geolocation.getCurrentPosition(
   function success(position) {
     // 当获取位置成功时运行此函数
     console.log('latitude', position.coords.latitude,
                 'longitude', position.coords.longitude);
   },
 function error(error_message) {
    // 当获取位置失败时运行此函数
    console.error('An error has occured while retrieving location', error_message)
    ipLookUp()
 }
});
} else {
  // geolocation 不支持
  // 通过其他方式获取地理位置
  console.log('geolocation is not enabled on this browser')
  ipLookUp()
}

现在我们有两种方式获取地理位置,我们还可以使用Google Maps Reverse Geocoding API通过坐标获取更详细的地址。
反向地理编码是一个将地理坐标转换成易于人读的地址。代码如下:

function getAddress (latitude, longitude) {
  $.ajax('https://maps.googleapis.com/maps/api/geocode/json? latlng=' + latitude + ',' + longitude + '&key=' + GOOGLE_MAP_KEY)
  .then(
    function success (response) {
      console.log('User's Address Data is ', response)
    },
    function fail (status) {
      console.log('Request failed.  Returned status of', status)
    }
   )
}
getAddress(6.4531, 3.3958)

输出如下:

现在我们把上面写的代码组合起来:

function ipLookUp () {
  $.ajax('http://ip-api.com/json')
  .then(
      function success(response) {
          console.log('User's Location Data is ', response);
          console.log('User's Country', response.country);
          getAdress(response.lat, response.lon)
},

      function fail(data, status) {
          console.log('Request failed.  Returned status of', status);
      }
  );
}
function getAddress (latitude, longitude) {
  $.ajax('https://maps.googleapis.com/maps/api/geocode/json? latlng=' + latitude + ',' + longitude + '&key=' + GOOGLE_MAP_KEY)
  .then(
    function success (response) {
      console.log('User's Address Data is ', response)
    },
    function fail (status) {
      console.log('Request failed.  Returned status of', status)
    }
   )
}
if ("geolocation" in navigator) {
  // 检查对当前的浏览器geolocation是支持/禁用
  navigator.geolocation.getCurrentPosition(
   function success(position) {
     // 当获取位置成功时运行此函数
     console.log('latitude', position.coords.latitude,
                 'longitude', position.coords.longitude);
     getAddress(position.coords.latitude,
                position.coords.longitude)
   },
function error(error_message) {
    // 当获取位置失败时运行此函数
    console.error('An error has occured while retrieving location', error_message)
    ipLookUp()
 }
});
} else {
  // geolocation 不支持
  // 通过其他方式获取地理位置
  console.log('geolocation is not enabled on this browser')
  ipLookUp()
}

 参考

发表评论