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
相关产品推荐
相关产品推荐

