如何修复 Web 应用的白屏问题
白屏几乎总是由两种情况之一造成:应用的 JavaScript 在绘制任何内容之前就崩溃了,或者 JavaScript 根本没有加载。打开浏览器控制台(右键 → 检查 → 控制台),阅读第一条红色错误信息,然后检查 网络 标签页中加载失败的文件。大多数原因是缺少环境变量、基础路径错误、构建没有完成,或者某个组件崩溃。
本指南介绍使用 React、Vue 或类似框架构建的单页应用(包括由 AI 搭建工具生成的应用),白屏问题在这类应用中最为常见。
页面为什么是白的
现代单页应用(SPA)发送给浏览器的 HTML 文件几乎是空的,大致如下:
<body>
<div id="root"></div>
<script type="module" src="/assets/index-a1b2c3.js"></script>
</body>
随后,JavaScript 会在这个空的 div 中构建整个页面。如果脚本加载失败,或者在渲染之前抛出了错误,这个 div 就会保持为空,于是你看到的就是白色。页面并没有以可见的方式“损坏”,它只是从未被绘制出来。
因此,修复工作总是从开发者工具开始,而不是直接在页面上进行。
第一步:查看控制台
打开开发者工具:右键点击页面并选择 检查,或按 F12(Mac 上为 Cmd+Option+I)。切换到 控制台 标签页,然后刷新页面。
注意第一条红色错误,后面的错误往往只是连带反应。它的内容会指向原因:
| 控制台信息(典型措辞) | 含义 | 跳转到 |
|---|---|---|
Cannot read properties of undefined (reading '...') | 代码期望的数据不存在 | 第四步 |
... is not defined / ... is not a function | 缺少导入、变量或设置 | 第四步或第三步 |
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html" | 某个脚本的 URL 返回了 HTML 页面而不是 JavaScript | 第二步 |
Uncaught SyntaxError: Unexpected token '<' | 同样的问题:期望得到 JavaScript,却得到了 HTML | 第二步 |
supabaseUrl is required、Missing API key 或类似信息 | 某个环境变量为空 | 第三步 |
Access to fetch ... has been blocked by CORS policy | 对其他域名的请求被拦截 | 参见如何修复 CORS 错误 |
| 完全没有错误 | 渲染成功,但页面什么也不显示,或被 CSS 隐藏了 | 第六步 |
复制完整的错误文本,包括文件名和行号。如果你使用的是 AI 搭建工具,直接把它粘贴到聊天中即可。
第二步:检查文件是否已加载
打开 网络 标签页,勾选 停用缓存,然后刷新页面。查看 .js 和 .css 文件的请求。
- JavaScript 文件返回 404 状态码:页面请求的文件在服务器上不存在。
- 状态码为 200,但类型是
text/html:服务器返回了一个页面(通常是index.html本身,因为 SPA 回退规则),而不是脚本。根本原因相同:文件不在页面所期望的位置。
常见原因如下:
基础路径错误。 如果应用部署在子文件夹下,例如 example.com/app/,但构建时却设置为从 /assets/... 加载文件,那么所有脚本请求都会失败。在 Vite 中,这一设置是 vite.config 中的 base 选项;在 Create React App 中是 homepage 字段;在 Next.js 中是 basePath。它必须与应用的实际部署位置一致。
过期的 index.html。 构建工具会给文件名加上内容哈希,例如 index-a1b2c3.js。新版本部署之后,旧文件就不存在了。如果浏览器或 CDN 仍缓存着旧的 index.html,它就会请求旧文件,结果什么也拿不到。强制刷新(Cmd+Shift+R 或 Ctrl+Shift+R)可以确认这一点。长期的解决方法是:对 index.html 使用较短或不缓存的响应头,而对带哈希的文件设置较长时间的缓存。
构建未完成或未部署。 如果构建失败,托管平台可能提供的是旧的或空的输出文件夹。请检查构建日志中的错误。
发布了错误的文件夹。 托管平台必须提供构建产物(通常是 dist 或 build),而不是项目的源代码文件夹。如果提供的是源代码,得到的 index.html 会指向 /src/main.tsx,而浏览器无法运行它。
第三步:检查环境变量
前端应用通常在构建时读取 API 地址或公开密钥等设置。如果线上构建中缺少某个变量,像 createClient(undefined, undefined) 这样的代码会立即抛出错误,页面就会变白。
需要了解的几点:
- 在 Vite 中,只有以
VITE_为前缀的变量可以在浏览器代码中使用,读取方式为import.meta.env.VITE_NAME。在 Create React App 中前缀是REACT_APP_;在 Next.js 中是NEXT_PUBLIC_。 - 这些值是在应用构建时写入的。构建之后再添加变量不会产生任何效果,必须重新构建并重新部署。
- 预览环境或本地计算机上可能有
.env文件,而生产构建中没有。请在托管平台上设置相同的变量。 - 带有这些前缀的内容最终都会进入公开的 JavaScript。只把公开的值放在这里,绝不要放入密钥。
一个快速的测试方法:在控制台错误中搜索设置名称附近的 undefined,或者直接问:
已发布的应用显示空白页面。请列出前端读取的每一个环境变量,检查线上构建中哪些变量缺失或为空,并在缺少变量时让应用显示清晰的错误信息,而不是空白页面。
第四步:修复崩溃
如果控制台显示的是普通的 JavaScript 错误,说明代码在渲染时崩溃了。AI 搭建应用中的典型原因包括:
- 数据尚未加载。 组件在
user到达之前就读取了user.name。修复方法是加入加载状态,或使用可选链(user?.name)。 - 数据为空。 新账户没有任何记录,而代码假设列表至少有一项。
- 数据结构不符合预期。 API 返回了一个错误对象,而不是代码所期望的列表。
- 缺少导入。 某个文件被重命名或移动之后。
- 在服务端渲染时使用了仅限浏览器的 API,例如在 Next.js 服务端组件中使用
window或localStorage。
把完整的错误、页面以及你当时登录的账户情况告诉 AI:
仪表盘页面对新用户显示空白。控制台:
TypeError: Cannot read properties of undefined (reading 'map'),位于ProjectList.tsx:18。我的账户有项目,所以它能正常显示。请修复它,使空账户显示“暂无项目”,并在预览中检查一个新账户。
第五步:添加错误边界
在 React 中,一个崩溃的组件就可能卸载整个应用,这就是为什么一个小 bug 会导致页面完全空白。错误边界是一个组件,它会捕获其下方的渲染错误,并改为显示备用内容。
在主要路由外围添加一个错误边界,显示“出了点问题”以及一个重新加载按钮,并将错误记录到控制台。请把页头和导航放在边界之外,使它们仍然能够渲染。
它并不能修复 bug,但访客看到的是一条提示,而不是空白屏幕,而你也能看到问题出在哪里。
第六步:没有错误,但仍然空白
如果控制台没有错误,并且脚本都已加载:
- 检查 Elements(元素)标签页。
<div id="root">内是否有内容?如果有,说明它已经渲染了,只是不可见:白色文字放在白色背景上、opacity: 0、display: none,或者有一个全屏元素遮挡了它。 - 检查路由器。 如果没有任何路由匹配当前 URL,并且没有“未找到”路由,某些路由器会什么都不渲染。请添加一个显示 404 页面的兜底路由。
- 检查挂载点。 代码必须挂载到一个确实存在的元素上。如果
index.html中是id="app",而代码查找的是root,那么什么都不会显示(React 通常还会记录一条错误)。 - 检查浏览器扩展。 试试无痕窗口。广告拦截器偶尔会拦截名称类似
analytics或ads的脚本。
只有刷新页面后才变白?
如果首页正常,但刷新 /dashboard 后显示白屏或 404,说明服务器不知道要为应用路由返回 index.html。这是路由回退的问题,详见如何修复部署后的 404 错误。
常见错误
- **阅读最后一条错误,而不是第一条。**第一条红色信息通常才是原因。
- **设置环境变量后没有重新构建。**前端变量在构建时就已固定。
- **只用自己的账户测试。**空账户导致的崩溃是最常见的白屏原因之一。
- **以为部署已经成功。**在调试代码之前,先检查构建日志。
- **把所有问题都归咎于浏览器缓存。**强制刷新几秒钟就能排除这一点;如果页面仍然是空白,那就是其他原因。
Mythex 中的白屏问题
如果预览是空白的,先检查应用是否在运行(打开 代码 → 终端),然后让 Mythex 启动正确的服务器,点击预览工具栏中的 刷新,或使用 /fix。如果已发布的网址是空白的,文档建议等待一分钟后强制刷新,在发布前确认环境变量和数据库已设置好,并检查你的托管额度。请记住,已发布的应用是一个快照:修复问题后需要重新发布。如果是某次修改导致的问题,可以在最近一条可用的回复上点击恢复到此节点,将项目回滚。相关内容请参阅文档中的故障排查和发布故障排查,也可以参阅我们关于调试 AI 搭建应用的通用指南。
白屏检查清单
- 已阅读控制台中的第一条红色错误
- 已在网络标签页中检查返回 404 或 HTML 的
.js/.css文件 - 基础路径与应用的部署位置一致
- 构建已完成,且发布的是构建产物文件夹
- 线上构建中已设置所有前端环境变量,并已重新构建
- 崩溃已修复,包括空账户和新账户的情况
- 已设置错误边界,今后的崩溃会显示提示信息
- 已为未知 URL 设置兜底路由
- 已通过强制刷新和无痕窗口测试
常见问题
为什么我的 React 应用显示白屏?
通常是因为 JavaScript 在渲染任何内容之前就崩溃了,或者 JavaScript 文件根本没有加载。打开浏览器控制台:其中的红色错误会告诉你是哪一种情况,以及错误发生在哪个文件和哪一行。
为什么我的应用在本地正常,部署后却显示空白页面?
最常见的原因包括:线上构建从未设置过环境变量;JavaScript 和 CSS 文件的请求路径错误(基础路径不匹配);以及缓存中过期的 index.html 指向了已经不存在的文件。
“Failed to load module script”是什么意思?
浏览器请求的是一个 JavaScript 文件,但拿到的却是一个 HTML 页面,通常是网站的 index.html 或一个错误页面。这说明文件路径有误,或服务器上根本没有这个文件,因此请检查构建产物和应用的基础路径设置。
如何避免一个 bug 让整个页面变成空白?
添加错误边界(Error Boundary)。在 React 中,错误边界是一个组件,它会捕获其下方页面部分的渲染错误,并显示一条备用提示,而不是把整个应用卸载掉。