You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS+Nginx部署的Create React App新版本上线后部分用户出现`Unrecognized token "<"`错误的咨询

解决CRA应用部署后出现Unrecognized token "<"的缓存问题

我之前帮好几个团队排查过几乎一模一样的问题!这个错误的根源确实和缓存脱不了干系,咱们一步步拆解:

为什么会出现这个错误?

这个报错本质是浏览器请求的是JS/CSS静态资源,但服务器返回的却是index.html的内容,浏览器把HTML当成JS解析,自然会在开头的<符号处报错。而新开窗口能解决,是因为新窗口会绕过浏览器的内存缓存,重新发起完整的资源请求,拿到了正确的文件。

具体到你的场景,原因大概率是:

  • Create React App打包后,JS/CSS这类静态资源都会带上唯一哈希后缀(比如main.abc123.js),这些文件是可以安全长期缓存的;但index.html是入口文件,里面记录了当前版本要加载的静态资源哈希。
  • 如果Nginx(或CDN)给index.html设置了过长的缓存时间,用户浏览器会一直用旧的index.html,而旧文件里引用的带旧哈希的静态资源,已经在你部署新版本时被替换掉了。当浏览器请求这些不存在的旧资源时,Nginx的单页应用路由配置(try_files $uri $uri/ /index.html)会把404请求fallback到index.html,于是浏览器拿到HTML却当成JS解析,就出现了这个报错。

怎么解决?

核心思路是:给带哈希的静态资源设置长缓存,给index.html设置无缓存/短缓存。

1. 调整Nginx配置

修改你的Nginx站点配置,添加针对性的缓存规则:

# 带哈希的静态资源(JS/CSS/图片等)可以长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
    expires 1y;  # 缓存1年
    add_header Cache-Control "public, immutable";  # 标记为不可变,避免浏览器重复验证
}

# 对index.html强制不缓存,确保每次都请求最新版本
location = /index.html {
    expires -1;
    add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate";
}

# 单页应用路由 fallback(保持原有配置即可)
location / {
    try_files $uri $uri/ /index.html;
}

2. 优化部署流程

部署新版本时,先上传所有带哈希的静态资源,最后再替换index.html。这样即使旧的index.html还在被用户访问,它引用的旧静态资源依然存在,不会出现404 fallback到index.html的情况,避免中间状态的报错。

3. 检查AWS CDN缓存(如果使用了)

如果你的应用前端用了CloudFront这类CDN,记得:

  • 对index.html单独设置缓存策略,TTL设为0或者很短(比如1分钟);
  • 带哈希的静态资源可以设置长TTL,无需手动失效缓存(因为哈希变化后,CDN会自动拉取新文件)。

验证方法

修改配置后,部署一个新版本,然后用浏览器的开发者工具(Network面板)查看:

  • index.html的响应头里Cache-Control应该是no-store, no-cache...;
  • 带哈希的JS/CSS文件的响应头里有Cache-Control: public, immutable和Expires字段。

内容的提问来源于stack exchange,提问作者Erik Craigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:02:47