NGINX静态资源缺失(304响应码)问题排查求助
字体静态资源加载异常排查与修复方案
核心问题定位
浏览器未发起字体资源请求,是因为收到NGINX返回的304 Not Modified响应后直接复用本地缓存,但缓存内的字体资源存在损坏、不完整,或缓存校验逻辑异常,导致图标无法正常渲染。
部署架构梳理
- Angular应用依赖字体等静态资源,构建后生成带内容哈希的资源文件名
- 应用打包进Docker容器,内置NGINX作为静态资源分发服务器
- 部署在OpenShift平台,请求链路:Route(SSL终止)→ Service → Pod(由DeploymentConfig管理)
问题表现细节
- 页面加载时部分字体资源无网络请求记录,对应图标无法显示
- CSS中字体引用为带哈希的路径(Angular构建自动生成):
@font-face { font-family: FontAwesome; src: url(fontawesome-webfont.2b13baa7dd4f54c9.eot?v=4.7.0); src: url(fontawesome-webfont.2b13baa7dd4f54c9.eot?#iefix&v=4.7.0) ...; }
- NGINX日志显示字体请求返回304状态码:
{"@timestamp": "2024-02-26T10:34:50+01:00","source": { "ip": "" },"http": {"request": { "method": "GET", "line": "GET /fontawesome-webfont.e9955780856cf8aa.woff2?v=4.7.0 HTTP/1.1", "bytes": 1268, "referrer": "https://<base_url>/styles.dc792cbafebe4f47.css" },"response": { "status_code": 304, "bytes": 214 }},"user_agent": { "original": "..." },"processing_time":"0.000"}
- 禁用浏览器缓存可临时恢复,但无法作为长期解决方案
排查与修复方案
1. 修正NGINX缓存头配置
当前静态资源的Cache-Control设置可能导致缓存校验逻辑冲突,调整为以下配置:
location ~* \.(ico|css|js|gif|jpe?g|png|svg|ttf|woff2?|otf)$ { expires 1y; add_header Cache-Control "public, immutable"; add_header ETag ""; # 禁用ETag,避免304校验逻辑异常 }
immutable标记告诉浏览器:资源文件名带哈希,更新时会自动更换路径,有效期内无需发起校验请求- 禁用ETag可避免服务器与浏览器间的校验逻辑不一致问题
2. 确认Angular构建配置
确保Angular构建时正确生成带内容哈希的资源文件名,避免资源更新后浏览器复用旧缓存:
检查angular.json中的outputHashing配置:
"build": { "options": { "outputHashing": "all" } }
3. 检查OpenShift Route缓存配置
验证OpenShift Route是否存在额外缓存配置,覆盖NGINX返回的响应头:
执行命令查看Route注解:
oc describe route <你的Route名称>
确认无haproxy.router.openshift.io/cache-default-duration等可能干扰缓存的配置
4. 清理Docker镜像内旧资源
确保Docker镜像构建时未残留旧版本静态资源:
- 在Dockerfile中添加构建前清理步骤,删除旧
dist目录内容 - 使用多阶段构建,仅复制最终构建产物到镜像,避免冗余资源
5. 明确声明字体MIME类型
虽然已有mime.types配置,可在NGINX中手动声明,避免解析错误:
types { font/woff woff; font/woff2 woff2; }
验证步骤
- 应用上述配置修改,重新构建Docker镜像并部署到OpenShift
- 首次访问页面,确认字体资源返回200状态码;后续访问无对应请求(因
immutable缓存生效) - 修改任意静态资源后重新构建部署,验证新资源正常加载,浏览器未复用旧缓存
内容的提问来源于stack exchange,提问作者Paul Evans
相关产品推荐
相关产品推荐

