全网都在搞的评论区、主页等显示IP地址功能

全网都在搞的评论区、主页等显示IP地址功能

背景

近大半年发现很多的应用, 不限于(微博,抖音,知乎、yuque、字节、微信等)都开放了 显示 IP 属地的显示,这个功能挺有趣,同时我也思考了一下,想在自己的项目中使用,现在就写下这篇文章谈谈让我做的实现思路和想法;

话说掘金什么时候出这个功能?

作为前端仔,先给掘金设计一波😀.

全网都在搞的评论区、主页等显示IP地址功能

实现

就两个问题, 获取ip, 再拿ip地址换地理位置信息(省市区)

下面我们以Node.js为例子

获取IP地址

Http header中可以获取到客户端在请求头中携带的IP地址

头部名词的解释

  • X-Forwarded-For:Web 服务器获取访问用户的真实 IP 地址,若存在代理,最左边是最原始客户端的 IP 地址;

在node.js中

koa为例子

在中间件函数中, 获取header里的x-forwarded-for子段

export default (ctx, next) => {
  const {
    method, body, query, header: { 'x-forwarded-for': ip },
  } = ctx.request;
  console.log(ip, 'ip地址’)
}

nginx的配置

如果你使用的nginx代理你的服务, 其实上面node里获取的真实ip那个子段, 依赖于nginx的转发。就是这行。 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

子段释义
  • $proxy_add_x_forwarded_for 记录真实的客户端IP地址,但是服务器中的日志需要有这个变量。

参考链接 nginx官方文档 (https://nginx.org/en/docs/http/ngx_http_proxy_module.html#var_proxy_add_x_forwarded_for)

nginx配置转发伪代码

server {
      listen 80;
           ...
              location  /api/ { 
              ...
              // 代理真实IP
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              ...
              proxy_set_header Connection "upgrade";
              proxy_pass http://127.0.0.1:8001/;
              proxy_redirect off;
        }
}

ip地址换地理位置

注册高德地图开放平台, 进入控制台(https://lbs.amap.com/)

创建一个应用

全网都在搞的评论区、主页等显示IP地址功能

在应用 创建一个apikey

全网都在搞的评论区、主页等显示IP地址功能

apikey创建好了

全网都在搞的评论区、主页等显示IP地址功能

使用IP定位API

文档链接(https://lbs.amap.com/api/webservice/guide/api/ipconfig)

如下, 传你的apiKey和ip地址即可换取省市区及经纬度

https://restapi.amap.com/v3/ip?key=XXX&ip=你的ip地址

返回示例

{
    "status""1", // 1为成功
    "info""OK",
    "infocode""10000",
    "province""浙江省",
    "city""杭州市",
    "adcode""330100",
    "rectangle""119.8824799,29.95931271;120.5552208,30.52048536"
}

node中使用

koa中间件中使用

const fetch = require('node-fetch');
export default async(ctx, next) => {
  const {
    method, body, query, header: { 'x-forwarded-for': ip },
  } = ctx.request;
  const info = await getLocation(ip);
  // console.log(info, '省市信息’)
    // {
    //   "status": "1",
    //     "info": "OK",
    //     "infocode": "10000",
    //     "province": "浙江省",
    //     "city": "杭州市",
    //     "adcode": "330100",
    //     "rectangle": "119.8824799,29.95931271;120.5552208,30.52048536"
    // }
  await next()
}
  
/*
 * ip获取省市信息
 * @param {} $ip
 * @returns 省市信息
 */

async function getLocation($ip{
  // 处理一下ip
  const ip = $ip.replace(/::ffff:/g'').split(',')[0];
  // 调用高德地图的
  const ipResult = await fetch(`https://restapi.amap.com/v3/ip?key=310d88b1f76599ee6a4b0bd50ba6bbd8&ip=${ip}`).then((res) => res.json()).catch(() => { });
  if (data && data.status === '1') {
      return ipResult;
  }
  return null;
}
  

其他ip换取地理信息方式

github发现一个离线的解析ip的库

Ip2region

ip2region v2.0 – 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。 github链接 (https://github.com/lionsoul2014/ip2region)

存储方式 & 业务分析

存储方式

  • 1、存Redis

    每次获取ip先从redis里找, 没有再去查询第三方API

  • 2、 搞个ip和地理信息对应表

    每次获取ip先从对应表, 没有再去查询第三方API

业务功能分析

评论里的IP信息

例如评论这种功能 , ip和评论绑定,是快照存(后续变动了不影响之前的评论)。

  • 这种每次从ip和地理信息对应表 查也可以。
  • 如果 要求不高, 不考虑后续扩展, 直接加个子段 把地理信息冗余到业务表里吧。
主页的IP信息

主页的位置信息要实时变的。

加个中间件 每次都去获取当前ip 判断地址变没变?

按一定策略, 在某个接口 加个异步方法,低频率判断。

比如在主页的某个接口,加一个方法,异步判断, 变化了,就更新到用户表。

总结两步
  • 1、异步判断ip地址变化。

  • 2、异步更新到用户表。

文章出自:https://juejin.cn/post/7154724417715568677

作者:浏览器API调用工程师


原文始发于微信公众号(前端24):全网都在搞的评论区、主页等显示IP地址功能

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/216541.html

(0)
李, 若俞的头像李, 若俞

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!