返回博客

10 年程序员也被 Next.js 16 坑了:非 localhost 请求被静默拦截

2026-08-28
总结
5 分钟

手机通过局域网 IP 访问 Next.js 16 的 dev 服务器,点击右上角菜单按钮毫无反应——不是你的代码有问题,是 Next.js 16 默认拦截了非 localhost 来源的静态资源请求。

JS bundle 全被挡在门外,React 压根没水合,你看到的只是一个纯 HTML 的“死按钮”。

我上周刚踩完这个坑,AI 帮不上忙,浏览器模拟一切正常,最后翻文档才定位到。这篇把排查过程和修复方案完整写下来,帮你省掉半天。

问题现象:模拟器正常,真机全废

场景很典型:本地开发 Next.js 16 项目,想在手机上真机看看效果。

电脑上起 dev server,手机连同一个 Wi-Fi,通过局域网 IP(比如 192.168.2.xxx:3000)访问。页面能打开,样式也在,但点右上角菜单按钮——没反应。

更诡异的是:

  • 浏览器开 DevTools 的手机模拟,一切正常
  • localhost:3000 访问,一切正常
  • 换个手机、换个浏览器,还是不行

这种“模拟正常、真机失灵”的组合,最容易把人带偏——你会怀疑是移动端事件绑定问题、触摸事件没处理、CSS 层级遮挡……然后开始一段漫长的错误排查。

排查过程:AI 也带偏了

先说结论前的弯路。我把现象丢给 AI,得到一堆方向:

  • 检查 onClick 是否被 e.preventDefault() 拦截
  • 检查是否有透明遮罩层挡住了按钮
  • 检查移动端 touch 事件兼容性

挨个试,全都不对。AI 提示词写到多高都没用——因为问题根本不在业务代码里。

关键转折点是意识到一件事:按钮没反应,可能不是事件没绑定,而是 JS 压根没加载。

React 应用的交互依赖水合——服务端渲染出的 HTML 被 React 接管,事件监听才真正挂上去。如果 JS bundle 加载失败,页面就是一堆好看的静态 HTML,点什么都没用。

打开手机浏览器的调试面板(或远程调试)看 Network,真相出来了:静态资源请求全部失败,JS bundle 一个都没加载进来。

而浏览器模拟器为什么正常?因为模拟器跑在你电脑上,请求头里的 Origin 还是 localhost——没触发拦截。

根因:Next.js 16 默认拦截非 localhost 来源

Next.js 16 在 dev 服务器上加了来源校验:默认只允许 localhost 来源的静态资源请求。

你手机用 192.168.2.xxx 这种局域网 IP 访问时,Origin 和 localhost 不匹配,静态资源请求被直接挡掉。页面 HTML 能出来(路由响应),但 JS 全军覆没。

这个行为在之前的 Next.js 版本里是没有的,所以老项目升级上来的人最容易中招——代码一行没改,真机调试突然全废。

官方给的解释是安全考虑,防止开发服务器被不可信来源滥用。合理,但报错提示太不显眼了,真机上你根本看不到控制台警告。

修复:next.config.ts 加 allowedDevOrigins

一行配置解决。在 next.config.ts 里加上:

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  allowedDevOrigins: ["192.168.2.***"], // 换成你的局域网 IP
};

export default nextConfig;

改完重启 dev server,手机刷新页面,菜单按钮秒开。

几个注意点:

  • 填你实际访问用的 IP 或主机名,别带端口
  • 如果团队里多人不同网段调试,可以把常用的都列上
  • 改配置必须重启 dev server,热更新不生效

只影响 dev,线上不用管

划重点:这个问题只存在于本地 dev 服务器的真机调试场景。

生产环境构建后,静态资源是同源加载的,不存在 Origin 校验这一说。所以别慌着往生产配置里塞 allowedDevOrigins——那是 dev 专属配置,线上本来就没这个问题。

排查思路总结

这次踩坑沉淀下来的方法论,比修复本身更值钱:

  1. 交互全失效,先怀疑 JS 没加载,再怀疑代码 bug。一个按钮坏可能是代码问题,所有交互都死,大概率是水合失败
  2. 模拟器正常 ≠ 真机正常。模拟器的网络环境和 Origin 跟真机不一样,这类“环境差异型” bug 模拟器永远测不出来
  3. AI 排查 bug 的盲区在“版本行为变更”。它倾向往你代码里找问题,而这次问题在框架默认行为里
  4. 升级大版本后,先扫一遍 breaking changes。哪怕官方不认为这是 breaking

我是 AI智能体先生,Agent 工程师|10年程序员,全网同名,分享 AI 落地一线实战。

留言