希望大家可以去我个人网站看本篇博客😀,纯手撸了一个月,希望大家能去看看,评论一两句/(ㄒoㄒ)/~~:
RoCBlog-Nginx反向代理解决客户端ip获取问题
任务
有访客记录的需求,所以需要获取客户端IP以及地理位置
- 可通过公共api获取:客户端信息
- 本项目前端使用
vue
框架,需要通过js
调用公共api获取信息
实现
第一想法
直接通过axios
发送请求获取信息
await axios.get("https://searchplugin.csdn.net/api/v1/ip/get ",{
baseURL:'/ipapi'
}).then(res => {
ip = res.data.data.ip
region=res.data.data.address
})
当然,不出意料的会造成跨域问题:
本博客域为(www.rocblog.cn) ,而请求的域为 (https://searchplugin.csdn.net/api/v1/ip/get) ,访问时理所应当的会造成跨域问题
第二想法
为了解决跨域问题,需要在nginx
中做一个反向代理,让前端发送请求给nginx
,然后由nginx
发送请求给公共api,然后将结果返回给前端。
于是我们将nginx
的配置文件nginx.conf
做出以下修改:
#在对应的server代码块中添加
location /ipapi/ {
proxy_pass https://searchplugin.csdn.net/api/;
}
然后将前端js
请求改为:
await axios.get("/v1/ip/get",{
baseURL:'/ipapi' # 将axios的baseUrl改为和nginx服务器中所对应的/ipapi
}).then(res => {
ip = res.data.data.ip
region=res.data.data.address
})
将axios
的baseUrl
改为和nginx
服务器中所对应的/ipapi
这样子前端所请求的路径就是https://www.rocblog.cn/ipapi/v1/ip/get
然后nginx会自动将https://www.rocblog.cn/ipapi 替换为我们刚刚所配置https://searchplugin.csdn.net/api/
这样子拼接下来其实就是和https://searchplugin.csdn.net/api/v1/ip/get/ 这个地址一样的。
做完以上处理其实我们的工作就差不多了,可以看到已经可以成功请求了
但是到记录一看就会发现问题
这里的ip不是我服务器的ip吗?根本不是真实的客户端ip
稍微一想就很容易明白其中的原因:
- 因为我们使用
nginx
代理转发的请求:客户端请求nginx
,nginx
请求公共api。无论客户端怎么改变,真正请求公共api的永远是nginx
(我的服务器),公共api获取不到真实的客户端ip。
然后我想清楚了这个问题之后,就去百度了一下:nginx怎么用真实IP发送请求
最终解决问题
其实方法也很简单,将刚刚的转发配置多增加两行配置(由于此处具体为何这样配置比较复杂本文不赘述,后续会专门写一篇讲这个问题。但其实从英文上也可以大致了解一二)
- proxy_set_header:设置转发的请求头,将真实的客户端ip添加进去
location /ipapi/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://searchplugin.csdn.net/api/;
}
添加后可以看到问题已经解决了