🌐 免费又安全!用 Nginx 巧妙绕过 IP-API 的 HTTPS 限制

🌐 免费又安全!用 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 查询功能现已集成到我的在线工具箱中,欢迎体验 👏
如果你也在做类似的小工具,不妨试试这个方案!

陶老师的工具箱

极速 · 实用 · 无需复杂操作,聚合开发、办公与生活场景的高效在线工具。开箱即用,极致体验。

去看看