本地项目如何实现公网访问?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 内网穿透 是一个非常简单有效的解决方案。

希望这篇文章能帮你少踩一些坑。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐