如何:不借助第三方服务粗略检测访客是否来自中国大陆
作为一个平时基本不怎么碰前端代码的开发者,以前偶尔遇到需要折腾前端的需求时,我总有一种「摸着石头过河」的感觉。
最近我就碰到了这样一个棘手的场景:我的某个网站上需要调用的一些服务,在中国大陆的网络环境下访问时经常会出现加载失败或极度缓慢的问题。 为了保证用户的浏览体验,比较理想的做法是:检测到访客来自中国大陆时,默认将他们重定向到支持大陆访问的同类型备用服务上。
传统的死胡同:IP 地址检测
从我固有的后端思维出发,脑海中跳出的第一个、也是最直觉的方案就是:判断来源 IP。
但仔细一推敲,这个方案的落地成本其实挺高:
获取真实 IP 的麻烦:现代网站基本都套了一层或多层 CDN(比如 Cloudflare),这就导致直接拿到的请求 IP 往往是 CDN 节点的,而不是用户的。即使通过
X-Forwarded-For去拿,也需要处理很多边界情况。并且,保存这些数据意味着更多合规问题。需要依赖 IP 数据库或第三方接口:为了知道 IP 归属地,你要么在服务器端维护一个 GeoIP 数据库,要么每次请求都去调用第三方的 IP 识别 API。前者太重,后者不仅增加了延迟,可能还要额外付费。
对于一个轻量级的前端需求来说,为了这么点事去大动干戈,显然把事情复杂化了。
醍醐灌顶:来自 AI 的降维打击
既然自己想不出好招,我决定去请教一下 AI。就在我和 AI 探讨有没有什么「纯前端、轻量级、不依赖外部服务」的替代方案时, AI 给了我一个让我直呼惊艳的思路:判断浏览器的时区。
放在以前,这种非主流的奇技淫巧我可能要在 Stack Overflow 的犄角旮旯里翻找大半天。而现在, 通过和 AI 几轮简单的自然语言对话,它就能精准捕捉到我的痛点,并且有来有回地讨论起不同做法的利弊, 例如是否应该判断一下浏览器语言,并列出采取不同实现策略时的影响面等等来帮助人类决策。
这个方案的核心逻辑非常简单:绝大多数中国大陆用户的电脑或手机,其系统时区都是默认设置好的、中国大陆的城市。
由于整个中国大陆作为时区中心的城市就那么几个,因此我们只需要利用浏览器原生的 Intl(国际化 API)
获取当前设备的时区,看看它是否属于中国大陆的时区集合即可。
这个方案的一个额外优点是它极其隐私友好:用户的 IP 地址我不需要关心也完全不需要收集, 也不会向我发送额外的数据,一切都在客户端完成。具体来说 AI 是这么做的:
- 定义中国大陆时区字典
首先,我们需要枚举出中国大陆的系统时区标识符,具体来说包括以下几个:
| |
- 检测
接下来,我们利用 Intl.DateTimeFormat().resolvedOptions().timeZone 来获取当前用户的时区,
并与我们的字典进行比对。为了防止极低版本浏览器不支持该 API 导致报错,我们可以用 try...catch
包裹一下:
| |
总结
只需短短几行代码,没有任何网络请求开销,不依赖任何第三方服务,我们就实现了一个极其轻量的「中国大陆访客检测」功能。 当然,这是一种非常粗略的检测,不过对我来说够用了,毕竟如果访客了解如何修改时区的话, 他们大概率知道自己正在做什么,也就不太需要我去考虑给他们一个预设能用的选项了。