前端检测用户地区

简介: 一个部署在国外的项目,在国内访问有些国外站点资源速度太慢,或无法访问,因此单独部署了一台香港的服务器用于中国大陆用户访问希望前端代码可以判断用户地区(主要是国内大陆用户),自动重定向到香港服务器的站点

需求描述


一个部署在国外的项目,在国内访问有些国外站点资源速度太慢,或无法访问,因此单独部署了一台香港的服务器用于中国大陆用户访问

希望前端代码可以判断用户地区(主要是国内大陆用户),自动重定向到香港服务器的站点


实现方式分析


一、地理位置API


使用 HTML5 navigator.geolocation.getCurrentPosition() 方法用来获取用户设备当前位置,可以得到经纬度数据


if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(showPosition);
} else {
  console.log("该浏览器不支持获取地理位置。");
}
function showPosition(position) {
  console.log(position.coords.latitude + ' , ' + position.coords.longitude);  
}


注意


出于隐私考虑,报告地理位置前会先请求用户许可。浏览器会弹框询问是否允许获取地理位置,只有允许后才能得到经纬度数据


测试结果


getCurrentPosition() 方法在 Ubuntu18 (台式机)上的 Chrome, Firefox 浏览器无法获取经纬度数据


Windows10 (台式机上的Win10虚拟机)上的 Chrome, Edge 浏览器可以获取到经纬度数据


Android 上的 Chrome, 自带浏览器 可以获取到经纬度数据

测试地址-菜鸟教程:developer.mozilla.org/zh-CN/docs/…


小总结


这种实现方式对于部分设备或者系统无法获取地位位置数据,可获取数据需要手动设置允许应用访问地理位置才行,得到的经纬度数据也无法直观用户地区,还需要再转换一下结果,此方案直接 PASS


二、判断用户IP


通过用户网络IP,使用第三方位置服务得到用户IP,经纬度,国家,城市地区等数据


1.腾讯位置服务


<script>
  // qq api callback function
  function f(res) {
    console.log(res)
    if (res.result.ad_info.nation === '中国') {
      console.log('china')
    } else {
      console.log(res.result.ad_info)
    }
  }
</script>
<script charset="utf-8" src="https://apis.map.qq.com/ws/location/v1/ip?key=xxx&callback=f&output=jsonp"></script>


使用 jsonp 方式输出实现,回调函数必须在API服务调用脚本上面,其他方式可以自行研究,代码在个人项目中有实现


注意


https://apis.map.qq.com/ws/location/v1/ip?key=xxx&callback=f&output=jsonp 链接里面的 key 参数需要自己注册一个腾讯开


发者账号,申请一个开发密钥,免费的, 因为有配额限制文档这里就不提供了(可以运行个人GitHub项目分析效果)

腾讯位置服务文档: lbs.qq.com/service/web…


2.搜狐位置服务


<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
<script>
  document.write(returnCitySN['cip'] + ', ' + returnCitySN['cid'] + ', ' + returnCitySN['cname']);
</script>


没有找到类似于腾讯位置服务的那种开发文档可以直接在浏览器访问地址查看定位结果,如下图,在个人项目中也有实现。


image.png



3.太平洋位置服务


http://whois.pconline.com.cn/ipJson.jsp


依然没有文档


直接在浏览器输入 url 得到结果,如下图,这里没有在个人项目中实现

image.png


小总结


也有其他服务商提供的免费服务,可以自行测试,参考链接中有人整理了好多

有些站点会有一个 language 的选项,不同的语言对应不同的站点,使用 localstorage 的方式记录用户最后选择的语言,用户再次访问时通过检测最后一次使用的语言自动重定向至对应站点。


优点: 通过调用第三方免费或付费服务可以不用再次转化数据得到用户地区,从而满足业务需求


缺点: 因为业务依赖于第三方服务,如果第三方服务不稳定或挂了,就影响业务功能了,不太靠谱


三、JavaScript 标准内置对象


// JavaScript standard built-in object
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
console.log(Intl.DateTimeFormat().resolvedOptions())
console.log(timeZone)
复制代码


Intl 对象是 ECMAScript 国际化 API 的一个命名空间,它提供了精确的字符串对比、数字格式化,和日期时间格式化


Intl.DateTimeFormat.prototype.resolvedOptions() 方法返回一个新对象,该对象的属性反映了语言环境以及在此DateTimeFormat对象初始化期间计算出的日期和时间格式设置选项


timeZone options参数中为此属性提供的值, 该值标识运行时的默认时区

MDN: developer.mozilla.org/zh-CN/docs/…


小总结


JavaScript 标准内置对象方式,相对前面两个类型的实现更简单靠谱


由于输出的是时区,这个 Intl.DateTimeFormat().resolvedOptions().timeZone 在国内输出结果是 Asia/Shanghai, 在国内时间是北京时间为准,国际时区方面中国城市是上海,这个在系统安装选择国家地区的时候也会遇到,我安装 Ubuntu 的时候选择中国地区也是上海


我 Google, Baidu, Bing 搜索引擎来来回回好几遍,也没看到这么个方式,然后大神告诉我还有这么一个实现的方式,据说是大神在搜解决方案的时候,看到 StackOverflow 中有人弱弱的回复了一下,论和大神一起做事的重要性


项目实现源码


Github:github.com/gywgithub/v…


参考链接


my.oschina.net/u/4337340/b…

developer.mozilla.org/zh-CN/docs/…

www.runoob.com/try/try.php…

zh.wikipedia.org/wiki/%E6%97…

www.iana.org/time-zones

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…


相关文章
|
13天前
|
Dart 前端开发 Java
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
【4月更文挑战第30天】本文探讨了Flutter应用中的内存泄漏检测与解决方法。内存泄漏影响性能和用户体验,常见原因包括全局变量、不恰当的闭包使用等。开发者可借助`observatory`工具或`dart_inspector`插件监测内存使用。解决内存泄漏的策略包括避免长期持有的全局变量、正确管理闭包、及时清理资源、妥善处理Stream和RxDart订阅、正确 disposal 动画和控制器,以及管理原生插件资源。通过这些方法,开发者能有效防止内存泄漏,优化应用性能。
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
|
14天前
|
JavaScript 前端开发
【Web 前端】JS中检测数据类型的有哪些?
【4月更文挑战第22天】【Web 前端】JS中检测数据类型的有哪些?
|
4月前
|
Web App开发 前端开发 JavaScript
前端检测用户地区
前端检测用户地区
|
5月前
|
JSON 前端开发 JavaScript
前端上传文件前检测文件数据🔍
前端上传文件前检测文件数据🔍
|
5月前
|
XML JSON 前端开发
前端代码重复度检测
前端代码重复度检测
69 0
|
7月前
|
前端开发 芯片
【芯片前端】保持代码手感——不重叠序列检测
【芯片前端】保持代码手感——不重叠序列检测
|
8月前
|
Web App开发 前端开发 JavaScript
前端必备技能---今天教会你如何高效使用Chrome调试与检测你的CSS代码
教会你如何高效使用Chrome调试与检测你的CSS代码
183 0
前端必备技能---今天教会你如何高效使用Chrome调试与检测你的CSS代码
|
9月前
|
前端开发
前端学习笔记202306学习笔记第三十八天-封装检测数据类型得方法1
前端学习笔记202306学习笔记第三十八天-封装检测数据类型得方法1
41 0
前端学习笔记202306学习笔记第三十八天-封装检测数据类型得方法1
|
9月前
|
前端开发
前端学习笔记202307学习笔记第五十七天-react源码-react检测是否使用了props之1
前端学习笔记202307学习笔记第五十七天-react源码-react检测是否使用了props之1
34 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第五十七天-react源码-react检测是否使用了props之2
前端学习笔记202307学习笔记第五十七天-react源码-react检测是否使用了props之2
36 0