找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3944

积分

0

好友

577

主题
发表于 2 小时前 | 查看: 3| 回复: 0

背景

在日常开发中,远程协作或处理支付回调等场景,常常需要远程访问我们本地的开发环境进行调试。这时候,一个可靠的内网穿透工具就至关重要。今天我们就来聊聊一个热门且强大的工具——FRP,并分享如何用它实现自定义域名访问本地服务,以及在此过程中可能遇到的“坑”。

FRP 官方资源

FRP 是一个专注于内网穿透的高性能反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议,且支持 P2P 通信。它能够帮助我们将内网服务安全、便捷地通过具有公网 IP 的服务器中转,暴露到公网。

应用架构

先简单介绍下我的项目背景。应用包含三个部分:

  • 小程序:技术栈为 UniApp。
  • 管理后台:技术栈为 Vue3 + Ant Design Vue。
  • 后端API:技术栈为 Spring Boot + Spring Data JPA。

在生产环境的部署架构比较简单,通过 Nginx 代理管理后台和后端API:
生产环境部署架构

用自定义域名远程调用本地服务

我们的目标是使用自己的域名(例如 dev.domain.com)来远程访问本地启动的服务。首先,你需要准备一台具有公网 IP 的服务器,并将你的域名通过 A 记录解析到该服务器的 IP 地址。

接着,根据你的操作系统下载对应版本的 FRP。压缩包内包含服务端(frps)和客户端(frpc)两个核心程序。我的演示环境是:服务器为 CentOS 7 (Linux),本地开发机为 macOS。
FRP GitHub Release 下载页面

配置与启动 FRP 服务端

编辑服务端配置文件 frps.toml

bindPort = 7000
auth.token = "666"
vhostHTTPPort = 80

webServer.addr = "0.0.0.0"
webServer.port = 7500
# dashboard 用户名密码,可选,默认为空
webServer.user = "admin"
webServer.password = "admin"

使用以下命令启动服务端:

./frps -c frps.toml

配置与启动 FRP 客户端

编辑客户端配置文件 frpc.toml,将 serverAddr 替换为你的服务器公网IP:

# 服务器外网IP
serverAddr = "x.x.x.x"
auth.token = "666"
serverPort = 7000

[[proxies]]
name = “web”
type = “http”
localPort = 3100
customDomains = [“dev.domain.com”]
locations = [“/”]

[[proxies]]
name = “api”
type = “http”
localPort = 8081
customDomains = [“dev.domain.com”]
locations = [“/api”]

使用以下命令启动客户端:

./frpc -c frpc.toml

下图清晰地展示了 FRP 代理本地项目的完整流程:
FRP代理架构流程图

遇到的第一个“坑”:Vite HMR 导致页面无限刷新

一切配置就绪后,访问 http://dev.domain.com,页面却开始不停刷新。打开开发者工具,发现 Vite 在疯狂地进行 __vite_ping
浏览器网络请求显示Vite HMR Ping

问题分析
这是因为本地启动的 Vite 项目默认开启了 HMR(热模块替换)。HMR 的核心是服务端(dev-server)与客户端(浏览器)之间建立一个 WebSocket 连接,用于实时推送代码更新。

WebSocket 的默认连接地址通常是 ws://本地或外网地址:本地端口。例如,本地端口是 3100,直接访问 http://localhost:3100 时,WebSocket 会连接 ws://localhost:3100,一切正常。

但当我们通过 FRP 代理访问 http://dev.domain.com(默认代理到服务器的 80 端口)时,浏览器试图建立的 WebSocket 连接地址变成了 ws://dev.domain.com:3100。然而,FRP 只代理了 80 端口的 HTTP 流量,并未代理 3100 端口的 WebSocket,导致连接失败,进而触发页面不断重试刷新。

解决方案
有两种思路可以解决:

  1. 保持端口一致:将 FRP 的 HTTP 代理端口也改为 3100。这样访问地址变为 http://dev.domain.com:3100,WebSocket 端口自然匹配。
  2. 修改 Vite 配置:在 vite.config.jsvite.config.ts 中,指定 HMR 的客户端端口为 FRP 代理的端口(如 80)。
    server: {
      hmr: {
        clientPort: 80,
      },
    },

参考 Vite 官方文档:https://cn.vitejs.dev/config/server-options#server-hmr

第二个“坑”:小程序 HTTPS 与证书链问题

上面的配置基于 HTTP 协议。但某些场景(如微信小程序)要求必须使用 HTTPS。我们可以从云服务商申请免费的 SSL 证书,下载后会得到证书文件。
下载的SSL证书和密钥文件

配置 FRP 支持 HTTPS

首先,修改服务端配置 frps.toml,启用 HTTPS 代理端口:

bindPort = 7000
auth.token = “666”
vhostHTTPPort = 80  # http 代理端口
vhostHTTPSPort = 443 # https 代理端口

然后,配置客户端 frpc_https.toml,使用 https2http 插件将本地的 HTTP 服务包装成 HTTPS:

serverAddr = “x.x.x.x”
serverPort = 7000
auth.token = “666”

[[proxies]]
name = “api”
type = “https”
localPort = 8081
customDomains = [“dev.domain.com”]

[proxies.plugin]
type = “https2http”
localAddr = “127.0.0.1:8081”

crtPath = “./dev.xxxx.com.public.crt”
keyPath = “./dev.xxxx.com.key”
hostHeaderRewrite = “127.0.0.1”
requestHeaders.set.x-from-where = “frp”

启动后,在浏览器访问 https://dev.domain.com,显示连接安全,证书信息也正常,似乎一切完美。
浏览器中显示的证书信息

小程序真机报错:证书链不完整

然而,在小程序真机上进行测试时,却收到了错误:

{“errno”:600001,“errMsg”:“request:fail errcode:-202 cronet_error_code:-202 error_msg:net::ERR_CERT_AUTHORITY_INVALID”}

为什么浏览器显示正常,小程序却报错?查看微信小程序官方对HTTPS的要求,其中明确提到了“证书的信任链必需完整”。
微信小程序HTTPS证书要求文档

我们立刻用专业的 SSL 检测网站(如 myssl.com)进行测试。结果“实锤”了问题根源:证书链不完整,这直接导致安全评级从 A 降到了 B。
SSL检测报告显示证书链不完整评级为B

修复证书链

在检测报告中,通常会提供“下载证书链”的选项,将完整的证书链文件下载下来。
证书链信息及下载链接

我们需要将完整的证书链(通常是一个包含中级CA和根CA的 .crt.pem 文件)与之前的服务器证书合并,或者在 FRP 服务端配置中正确指定证书链文件。重启 FRP 服务端后,再次检测,安全评级恢复到了 A。
修复证书链后的SSL检测评级为A
此时,小程序真机访问也完全正常了。这涉及到 HTTPS 和 TLS 握手的底层机制,对于移动端特别是有着严格安全沙箱的小程序环境,完整的证书信任链是强制要求。

总结

  1. FRP 工具:包含服务端 (frps) 和客户端 (frpc),支持 TCP、UDP、HTTP、HTTPS 等多种协议,是解决内网穿透需求的利器。
  2. Vite 代理注意:使用 FRP 代理 Vite 开发服务器时,务必注意 HMR 的 WebSocket 端口问题,确保本地端口与代理端口一致,或通过 clientPort 参数显式指定。
  3. 小程序 HTTPS 更严格:相较于浏览器,微信小程序等移动端环境对 HTTPS 证书的校验更为严格,必须保证证书链完整,否则会导致请求失败。这是开发中非常容易忽略的一个关键点。

希望这篇结合真实踩坑经历的 FRP 使用指南能对你有所帮助。如果在部署或网络配置中遇到其他问题,欢迎到 云栈社区 交流讨论。




上一篇:STM32按键检测进阶:FIFO机制与状态机的嵌入式程序框架与代码实现
下一篇:《集异壁》解构:哥德尔定理如何串联巴赫音乐与艾舍尔画作的递归宇宙
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-11 10:43 , Processed in 0.826398 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表