🌐 免费又安全!用 Nginx 巧妙绕过 IP-API 的 HTTPS 限制
在开发一个轻量级 IP 查询工具时,我遇到了一个典型但棘手的问题:如何在 HTTPS 网站中安全地调用仅支持 HTTP 的免费 IP 地理位置 API?
市面上有不少成熟的 IP 查询服务,但大多数都采用“免费有限、高级收费”的模式。考虑到我的使用场景并发不高、功能简单,实在没必要为这类工具付费。经过一番调研,我锁定了 ip-api.com —— 它提供无需 API Key 的免费接口,每分钟最多 45 次请求,完全够用。
然而,一个隐藏的“坑”出现了:免费版 ip-api.com 不支持 HTTPS!
这意味着,如果我的网站部署在 HTTPS 环境下(如今几乎所有的现代网站都如此),直接从前端调用 http://ip-api.com 会触发浏览器的混合内容(Mixed Content)拦截,请求根本发不出去。
🛠️ 解法:用 Nginx 做反向代理
最优雅的解决方案是:让前端请求同源的 /api/ip/ 路径,由 Nginx 代理转发到 ip-api.com 的 HTTP 接口。这样既绕过了浏览器的安全限制,又保持了代码的简洁。
基础配置如下:
# 反向代理到 ip-api(保留路径)
location /api/ip/ {
proxy_pass http://ip-api.com/; # 注意末尾斜杠!
proxy_set_header Host ip-api.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 3s;
proxy_read_timeout 5s;
}但问题还没完!
🎯 关键细节:如何让 API 返回用户的真实 IP?
我发现,即使设置了 X-Forwarded-For,ip-api.com 并不会用它来识别客户端 IP。结果是:当不显式传入 IP 时,API 总是返回我服务器的公网 IP,而不是访问用户的 IP —— 这显然不符合预期。
解决办法是:在 Nginx 层主动把用户的真实 IP($remote_addr)拼接到请求路径中。
于是,我新增了一个精准匹配的路由:
# 2. 不带 IP 的请求:自动注入客户端 IP
location = /api/ip/json {
proxy_pass http://ip-api.com/json/$remote_addr$is_args$args;
proxy_set_header Host ip-api.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 3s;
proxy_read_timeout 5s;
}
现在,当用户访问 https://your-site.com/api/ip/json 时,Nginx 会自动将其重写为:
http://ip-api.com/json/123.123.123.123
其中 123.123.123.123 就是用户的真实 IP。完美!
✅ 总结
通过 Nginx 反向代理 + 路径重写,我们成功实现了:
- 在 HTTPS 网站中安全调用 HTTP 的免费 IP API;
- 自动获取并传递用户真实 IP,确保查询结果准确;
- 无需付费、无需注册、零代码侵入。
这个 IP 查询功能现已集成到我的在线工具箱中,欢迎体验 👏
如果你也在做类似的小工具,不妨试试这个方案!