Vue3 怎么获取用户的 IP 地址?这些方法和细节要注意!
做项目时,不少场景需要获取用户 IP——比如统计访问来源、实现地域化功能、做安全风控等,但 Vue3 作为前端框架,获取 IP 可不是“调个 API 就能解决”的事,得先搞清楚前后端的网络边界、浏览器安全限制这些底层逻辑,下面从“能不能直接获取”“具体实现方法”“场景差异”等角度,把这件事讲透。
前端能直接获取用户公网 IP 吗?
先明确结论:浏览器环境下,前端 JavaScript 没办法直接拿到用户的公网 IP。
原因和浏览器的安全机制有关:IP 属于网络层的“敏感信息”,浏览器为了防止隐私泄露,不会把这类底层网络数据直接暴露给前端脚本,打个比方,浏览器就像“信息门卫”,只给前端开放 DOM 操作、Ajax 请求这些“必要权限”,像 IP 这种涉及用户隐私的信息,得“绕个弯”才能拿到。
那前端想获取 IP,只能走两条路:借助第三方公开 API(让第三方服务器帮我们返回用户 IP),或者依赖后端服务(后端拿到 IP 后再传给前端),这两种思路对应不同场景,下面分开拆解。
用第三方 API 实现前端获取 IP(Vue3 怎么写?)
很多平台提供了免费的“查询 IP”服务,原理是:用户前端发请求到第三方服务器,第三方服务器能拿到请求的源 IP,再把这个 IP 打包返回给前端。
步骤 1:选靠谱的第三方 API
推荐几个常用且稳定的(免费版有请求频率限制,生产环境慎用):
- ipapi.co:返回 JSON 格式,包含 IP、国家、城市、经纬度等信息,支持 HTTPS,示例请求:
https://ipapi.co/json。 - ipify.org:专注返回公网 IP,极简轻量,请求:
https://api.ipify.org?format=json。 - 淘宝 IP 库:国内访问更快,返回运营商、地域信息,请求:
https://taobao.com/service/getIpInfo.php?ip=你的IP(不传ip参数时,默认返回当前请求 IP)。
步骤 2:Vue3 中发起请求(以 ipapi.co 为例)
假设用 axios 发请求,先装依赖:npm i axios,再在组件里写逻辑:
<template>
<div>
<button @click="getIp">获取IP</button>
<p v-if="ipInfo">公网IP:{{ ipInfo.ip }}</p>
<p v-if="ipInfo">所在国家:{{ ipInfo.country_name }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import axios from 'axios'
const ipInfo = ref(null)
const getIp = async () => {
try {
// 发请求到第三方API
const res = await axios.get('https://ipapi.co/json')
ipInfo.value = res.data
} catch (err) {
console.error('获取IP失败:', err)
// 这里可以加用户提示,比如弹Toast告知失败
}
}
</script>
要避开的“坑”
- 跨域问题:第三方 API 必须支持 CORS(大部分知名服务都支持),否则浏览器会拦截请求,像
ipapi.co这类国际服务,响应头里会有Access-Control-Allow-Origin: *,所以能直接调用。 - 隐私合规:如果项目面向欧盟用户,得遵守 GDPR——获取 IP 前要明确告知用途并征得用户同意;国内也要遵守《个人信息保护法》,别把 IP 用于违规场景。
- 稳定性风险:免费 API 可能突然限流或宕机(比如某天
ipapi.co服务器维护,你的功能就会崩),生产环境建议自建后端服务,或购买付费 API(ipinfo.io的付费版,稳定性更高)。
前后端配合,后端拿 IP 后传给前端
如果项目对数据安全性、稳定性要求高(比如企业级应用、合规性严格的场景),更推荐后端获取 IP,再通过接口传给前端。
为什么后端能拿到 IP?
当用户访问后端服务器时,HTTP 请求里会携带客户端的源 IP(原理是 TCP/IP 协议的“源地址”字段),后端框架(Node.js 的 Express、Python 的 Django/Flask)能直接读取这个 IP。
但如果项目用了 Nginx 反向代理,后端拿到的可能是“代理服务器的 IP”,这时候得配置 X-Forwarded-For 头(代理服务器会把用户真实 IP 放到这个请求头里,再传给后端)。
步骤 1:后端写接口(以 Node.js + Express 为例)
先装依赖:npm i express cors,然后写服务:
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors()) // 允许跨域
app.get('/getIp', (req, res) => {
// 优先从 X-Forwarded-For 取(反向代理场景),否则取 req.ip
const userIp = req.headers['x-forwarded-for'] || req.ip
res.json({ ip: userIp })
})
app.listen(3000, () => {
console.log('后端服务启动:http://localhost:3000')
})
步骤 2:Vue3 前端调后端接口
和调第三方 API 逻辑类似,用 axios 发请求:
<template>
<div>
<button @click="getBackendIp">从后端拿IP</button>
<p v-if="backendIp">后端返回的IP:{{ backendIp }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import axios from 'axios'
const backendIp = ref(null)
const getBackendIp = async () => {
try {
const res = await axios.get('http://localhost:3000/getIp')
backendIp.value = res.data.ip
} catch (err) {
console.error('后端接口请求失败:', err)
}
}
</script>
反向代理下的 IP 处理(关键细节!)
如果后端前面挂了 Nginx,得在 Nginx 配置里加上这段(让代理服务器把用户真实 IP 传给后端):
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000; # 转发到后端服务
proxy_set_header X-Forwarded-For $remote_addr; # 把用户真实IP传给后端
}
}
这样后端才能从 X-Forwarded-For 里拿到用户的真实公网 IP;否则,后端拿到的只是 Nginx 服务器的 IP,等于“白忙活”。
公网 IP 和内网 IP,别搞混了!
很多同学做项目时会疑惑:“为什么本地测试拿到的 IP 是 168.x.x?” 这得先分清两个概念:
- 公网 IP:整个互联网中唯一的地址(比如你家宽带拨号后,运营商分配的 IP)。
- 内网 IP:局域网内的私有地址(
168.0.xxx、0.0.xxx),只能在局域网内通信。
前端不管怎么折腾,都拿不到用户的内网 IP(浏览器安全策略直接拦截),后端如果部署在局域网内(比如公司内网服务器),拿到的也只是“局域网内的 IP”;只有后端部署在公网服务器上,才能拿到用户的公网 IP。
实际项目里的避坑指南
除了技术实现,这些“非技术细节”也能决定项目稳不稳:
隐私合规是红线
IP 属于“个人信息”(能定位到个体),
- 国内项目:要符合《个人信息保护法》,获取 IP 前必须明确告知用户用途(收集 IP 用于统计访问地域”),并征得用户同意。
- 国际项目:欧盟 GDPR 要求更严格,甚至需要用户“主动点击授权”后才能收集。
举个例子:如果做用户行为分析,要在隐私政策里写明 “收集 IP 仅用于聚合分析,不关联个人身份”,并提供开关让用户选择是否同意。
第三方 API 的“备胎方案”
免费 API 说崩就崩,生产环境建议:
- 自建后端服务:用云服务器自己搭个“获取 IP”的接口(成本低,稳定性高)。
- 购买商业 API:
ipinfo.io的付费版,不仅稳定性强,还能返回更详细的地域、企业信息。
开发 vs 生产环境的逻辑区分
本地开发时,前端调后端接口拿到的可能是 0.0.1 或内网 IP,这是正常现象——生产环境部署到公网服务器后,才能拿到真实公网 IP,可以在代码里加环境判断,自动切换请求地址:
// 根据环境变量切换请求地址 const apiBase = import.meta.env.PROD ? 'https://your-prod-domain.com/api' : 'http://localhost:3000'
处理 IP 的“多值”情况
如果用户经过多层代理(CDN + Nginx),X-Forwarded-For 里可能有多个 IP(格式像 clientIP, proxy1IP, proxy2IP),这时候后端要取第一个非空值:
// Node.js 中处理多 IP 的情况
const getRealIp = (req) => {
const xff = req.headers['x-forwarded-for']
if (xff) {
return xff.split(',')[0].trim() // 取第一个 IP
}
return req.ip
}
封装复用:写个“获取 IP”的组合式函数
如果项目中多个组件需要获取 IP,把逻辑封装成组合式函数,能减少重复代码:
// src/composables/useGetIp.js
import { ref } from 'vue'
import axios from 'axios'
export const useGetIp = (apiUrl) => {
const ipData = ref(null)
const error = ref(null)
const fetchIp = async () => {
try {
const res = await axios.get(apiUrl)
ipData.value = res.data
error.value = null
} catch (err) {
error.value = err.message
ipData.value = null
}
}
return { ipData, error, fetchIp }
}
然后在组件里复用:
<template>
<div>
<button @click="fetchIp">获取IP</button>
<p v-if="ipData">IP信息:{{ ipData }}</p>
<p v-if="error" style="color: red;">错误:{{ error }}</p>
</div>
</template>
<script setup>
import { useGetIp } from '../composables/useGetIp.js'
// 用 ipapi.co 的 API
const { ipData, error, fetchIp } = useGetIp('https://ipapi.co/json')
</script>
不同场景选不同方案
- 快速 Demo、小项目:直接用第三方 API(
ipapi.co),代码少、见效快,但要接受“稳定性风险”。 - 生产级项目、合规性要求高:前后端配合,后端自己处理 IP 逻辑,再通过接口给前端,还要做好反向代理配置、隐私声明。
别幻想“前端能不能偷偷拿内网 IP”——浏览器根本不允许,这是为了用户安全,理解前后端的网络边界,才能少走弯路~
(延伸思考:如果要做“根据 IP 显示所在城市”,除了第三方 API 返回的地域信息,也可以自己维护 IP 库(比如纯真 IP 库),后端查库后返回更精准的信息——不过这又是另一个技术方向了~)
一句话记住关键逻辑
- 前端自身拿不到 IP,得靠第三方 API 或 后端;
- 第三方 API 快捷但不稳,生产优先后端方案;
- 反向代理要配
X-Forwarded-For,否则 IP 会“拿错”; - 隐私合规是红线,收集 IP 必须明说用途 + 用户授权。
能帮你理清 Vue3 获取 IP 的技术逻辑和实战细节~如果还有疑问,评论区随时聊~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网



