本地项目如何实现公网访问?ngrok 内网穿透完整踩坑指南(Invalid Host header + localhost 接口问题)
本地项目如何实现公网访问?ngrok 内网穿透完整踩坑指南(Invalid Host header + localhost 接口问题)
在本地开发 Web 项目时,经常会遇到一个非常真实的问题:
- 本地服务只能
localhost访问 - 手机无法调试前端页面
- webhook 无法回调
- 同事或客户无法访问你的开发环境
例如我的本地开发环境是:
前端:[http://localhost:8081](http://localhost:8081)
后端:[http://localhost:8080](http://localhost:8080)
MinIO:[http://localhost:9000](http://localhost:9000)
这些服务在本地都可以正常运行,但一旦需要 外网访问,问题就来了。
比如:
- 手机访问页面接口失效
- 图片无法加载
- 登录请求失败
这时候就需要使用 内网穿透工具。
常见方案包括:
| 工具 | 特点 |
|---|---|
| ngrok | 最简单,适合快速调试 |
| frp | 稳定,可自建 |
| cpolar / natapp | 新手友好 |
本文记录我使用 ngrok 实现本地服务公网访问的完整踩坑过程。
一、使用 ngrok 穿透本地服务
下载并安装 ngrok 后,可以直接运行:
.\ngrok.exe http 8080
启动后会生成一个公网地址:
https://xxx.ngrok-free.dev -> http://localhost:8080
此时:
- 外网可以访问你的本地服务
- 手机流量可以调试网页
- webhook 可以回调
看起来很简单,但在实际使用过程中,我遇到了不少坑。
二、实际踩到的几个坑
下面这些问题,基本是使用 ngrok 内网穿透 时最常见的。
1. ngrok 版本限制问题
一开始我使用的是旧版本 ngrok。
运行后提示:
ERR_NGROK_4018
随后又出现:
ERR_NGROK_121
原因是:
ngrok 2.x 已经停止支持。
解决方案
升级到 ngrok 3.x 并配置 token。
首先需要在 ngrok 官网注册账号:
https://dashboard.ngrok.com/signup
注册并登录后,进入 Dashboard, 获取 Authtoken
登录后进入以下页面:

这一串 长字符串就是你的 Authtoken。
进入 ngrok.exe 所在目录,在 PowerShell 中运行:
.\ngrok config add-authtoken 你的token
配置完成后即可正常使用。
2 HTTP / HTTPS 协议错误
一开始我的命令写成了:
https://localhost:8080
但本地服务实际上是:
http://localhost:8080
导致请求无法到达。
正确命令
.\ngrok http 8080
ngrok 会自动生成 HTTPS 公网地址。
3 Invalid Host header
这是很多 Vue / Vite 项目会遇到的问题。
错误信息:
Invalid Host header
原因
前端开发服务器默认会进行 Host 校验。
而 ngrok 转发的域名是:
xxx.ngrok-free.dev
与 localhost 不一致。
因此被开发服务器拒绝。
解决方案
使用 --host-header 参数:
.\ngrok http 8080 --host-header=localhost:8080
推荐完整命令:
.\ngrok http 8080 --host-header=localhost:8080 --region ap
这样 ngrok 会自动重写 Host 头。
4 前端接口写死 localhost
这是最容易忽略的问题。
例如前端代码:
axios.get("http://localhost:8080/api/login")
当手机访问网页时:
localhost 指向手机本机
所以接口调用一定失败。
解决方案
使用 相对路径
axios.get("/api/login")
或者使用 环境变量配置 API 地址。
5 ngrok 免费版只能使用一个 Session
我原本计划穿透两个端口:
8080 前端
9000 MinIO
但 ngrok 免费版存在限制:
- 默认只能建立 一个 Session
- 只能使用 一个公网域名
因此同时开启两个端口时:
8080
9000
ngrok 会把两个端口绑定到同一个域名。
结果导致:
- 有时访问 8080
- 有时访问 9000
- 前端页面无法加载 MinIO 图片
三、最终解决方案
最简单的方式是:
只穿透一个端口(8080)
然后通过前端代理转发到 MinIO。
例如在 vite.config.js 中配置:
proxy: {
'/minio-data': {
target: 'http://localhost:9000',
changeOrigin: true,
pathRewrite: {
'^/minio-data': ''
}
}
}
这样访问:
https://你的ngrok域名/minio-data/xxx.jpg
会自动转发到:
http://localhost:9000/xxx.jpg
成功解决:
- MinIO 图片加载
- ngrok 单隧道限制
四、最终成功配置
最终使用命令:
.\ngrok.exe http 8080 --host-header=localhost:8080 --region ap
运行成功后:
Session Status: online
ngrok 显示:
https://xxx.ngrok-free.dev -> http://localhost:8080
此时:
- 本地浏览器可以访问
- 手机流量可以访问
- 页面正常加载
- MinIO 图片可以读取
五、结语
如果你在开发项目时遇到:
- 手机无法调试
- 外网无法访问本地服务
- webhook 无法回调
那么 ngrok 内网穿透 是一个非常简单有效的解决方案。
希望这篇文章能帮你少踩一些坑。
更多推荐



所有评论(0)