先说结论
手机打不开 http://localhost:5173,因为手机上的 localhost 指的是手机自己,不是你的电脑。想在手机上看电脑上跑着的 dev server,要么让手机和电脑在同一个网络里、直接访问电脑的 IP,要么用 Tailscale、ngrok、Cloudflare Tunnel 这类工具把端口送出去。
如果你是在手机上让 Codex 或 Claude Code 改网页,人根本不在电脑前,BotBus 还多一条路:agent 改完自己起 dev server,用 botbus preview 把它分享回你手机上的这条任务,你在 app 里点开就能看,不用开端口,也不用配 VPN。这个功能目前只有 Mac 版有,下面分开讲各种办法适合什么情况,以及 BotBus 这条路的边界。
为什么手机打不开 localhost
dev server 默认只监听 127.0.0.1,也就是只接受本机发来的请求。这是有意为之:开发期的服务器往往没有鉴权、会暴露源码映射和调试接口,不该让局域网里的其他人随便访问。
所以「手机上看 localhost」其实是两个问题:
- 怎么让手机的请求到达电脑上的那个端口;
- 到达之后,dev server 认不认这个请求——新版 Vite 会检查
Host头,不认识的主机名直接拒绝;Next.js 的开发服务器对跨站来源也有检查;热更新(HMR)还要额外走一条 WebSocket。
前一个问题各种工具都能解决,后一个问题常常要你自己去改配置。
几种常见办法,各适合谁
同一 Wi-Fi 下访问电脑 IP。 让 dev server 监听所有网卡(Vite 是 vite --host,Next.js 是 next dev -H 0.0.0.0),然后在手机浏览器里打开 http://<电脑的局域网 IP>:<端口>。免费、零依赖、延迟最低,适合坐在电脑旁边、用真机检查响应式布局。缺点是手机必须和电脑在同一个网络里,公司网络可能隔离设备,而且整个局域网都能访问这个端口。
Tailscale 等组网工具。 手机和电脑装上同一个 tailnet 以后,手机能用电脑的 tailnet 地址访问端口,人不在同一个网络也行。适合本来就在用 Tailscale、想长期从外面访问自己机器的人。代价是两端都要装、要登录,dev server 仍然要监听 0.0.0.0 或 tailnet 网卡,有些开发服务器还要把这个主机名加进白名单。
ngrok、Cloudflare Tunnel 这类公网隧道。 一条命令把本机端口变成一个公网 HTTPS 地址,手机在哪儿都能打开,还能发给同事看。适合要给别人看效果的情况。要注意的是地址是公开的,除非你另外配了访问控制;Vite 这类工具会拦下不认识的隧道域名,要在 server.allowedHosts 之类的配置里放行。
这些办法都可行,问题在于:它们都要求你在电脑前操作一次。 起 dev server 时加参数、开隧道、把地址抄到手机上——人在电脑旁边时这不算什么;可如果你是在地铁上用手机让 agent 改页面,agent 改完了,你却没法看到它改成什么样,只能等回到电脑前再说。
BotBus 的做法:agent 自己把预览发回手机
从手机新建或续聊的 Codex、Claude Code 任务里,BotBus 会告诉 agent「用户不在电脑前」,并给它一个叫 botbus 的命令行与 MCP 工具,用来把截图、文件、链接和本地网页分享回手机上的这条任务。网页预览有三种来源:
- 已经在跑的端口:
botbus preview --port 5173 - 交给 BotBus 托管的 dev server:
botbus preview --port 5173 --cmd "npm run dev",BotBus 起进程、等端口就绪,停止分享时把进程一起收掉 - 一个静态目录:
botbus preview --dir dist
通常你不用记这些命令。在手机上说一句「改好以后起 dev server,把预览发给我」就行,agent 会自己调用。分享成功后,任务的「产物」里会多出一项预览,Mac 版还会自动截一张手机尺寸的缩略图挂在同一条任务上,让你不点开也能先看个大概。

点开预览,iPhone 上在 app 内置的浏览器里打开,Android 上在应用内的 WebView 里打开。页面是真的在电脑上跑着:可以点、可以滚动、可以填表单;你在手机上续聊让 agent 改样式,dev server 热更新后页面跟着刷新。

它是怎么连过去的
电脑上的 BotBus 主动连到 Relay,每个预览一条隧道,所以不需要在路由器或防火墙上开任何端口,dev server 也继续只监听 localhost。手机每次打开预览,都要先用自己的配对凭据向 Relay 换一张一次性的入口票据(60 秒内有效、用过即废),换到的会话 cookie 只对这一个预览的子域名有效。
转发到本机时,BotBus 把 Host 和 Origin 改写成 localhost:<端口>,所以 Vite、Next.js、webpack-dev-server 看到的请求跟你在电脑浏览器里打开一样,不用去改 allowedHosts;HMR 用的 WebSocket 也一起代理。
什么时候结束
一个预览默认存活 2 小时,到期自动结束;同一台 Mac 同时最多分享 5 个。在 Mac 菜单栏面板的「正在分享」里能看到每个预览的来源、剩余时间和隧道是否连着,可以逐个停止。退出 BotBus、解除配对时,所有预览和 BotBus 托管的 dev server 都会停掉。
限制与边界
- 只有 Mac 版有开发预览。 Linux 与 Windows 版的 BotBus 不提供开发预览(也没有电脑屏幕控制),手机上的「操作电脑」在那两个平台上只有文件和终端。
- 只在手机发起或续聊的任务里能用。
botbus工具靠每条手机任务一个的临时 token 鉴权,在电脑上自己开的会话里、或者手动在终端里运行它,会返回「任务 token 无效」。BotBus 重启后旧 token 全部作废,从手机再续聊一次就会重新签发。目前这套工具注入给 Codex 与 Claude Code。 - 开发预览不在端到端加密范围内。 BotBus 的任务、对话、命令和远程操作画面都是端到端加密的,但浏览器要直接请求网页里的各种资源,只能由服务器代理,所以预览页面的内容会以明文经过 Relay,只在你分享期间可以访问。涉及真实客户数据或密钥的页面,不要用预览分享,详见安全说明。
- 写死的
localhost:<其他端口>不通。 隧道只转发你分享的那一个端口。前端如果直接请求http://localhost:8080/api,在手机上会失败,因为那是手机自己的 localhost。BotBus 给 agent 的说明里会引导它改用相对路径或 dev server 的代理(例如 Vite 的server.proxy)。 - 大请求有上限。 单个请求体最多 16 MiB,本机 30 秒内不开始响应会超时,适合看页面效果,不适合拿来传大文件或压测。
- 电脑要开着、联网。 预览的每个请求都要从隧道转回你的电脑,Mac 一睡、断网,页面就打不开了;怎么让电脑别睡可以看这篇。
常见问题
不装 BotBus,最简单的办法是什么?
坐在电脑旁边的话,用 vite --host 或 next dev -H 0.0.0.0 让 dev server 监听所有网卡,手机连同一个 Wi-Fi,打开电脑的局域网 IP 加端口即可。人不在同一个网络里,就用 Tailscale 或公网隧道。
预览链接能发给同事看吗?
不能。预览要用你配对过的手机换一次性票据才能打开,直接复制地址给别人,对方只会看到一个提示「回 BotBus 重新打开」的说明页。要给别人看,用 ngrok、Cloudflare Tunnel 这类公网隧道更合适。
我在电脑上跑的 dev server,能在手机上手动打开吗?
BotBus 的预览由 agent 在手机任务里调用 botbus preview 发起,手机端没有「随便输入一个端口打开」的入口。最直接的做法是在手机上开一条任务或续聊,让 agent 把正在跑的端口分享过来。
支持 HMR 热更新吗?
支持。BotBus 会代理 dev server 的 WebSocket,所以你在手机上让 agent 改代码,页面会像在电脑上一样热更新。
手机预览和「操作电脑」有什么不同?
预览是把一个网页送到手机的浏览器里,内容经服务器代理、不在端到端加密范围内;「操作电脑」是看电脑的实时屏幕、操作文件和终端,全程端到端加密。只想看网页效果用预览;要点电脑上的弹窗、看模拟器,就用操作电脑。想试试的话,从下载区装最新版 BotBus。