目录
一、本地:确定构建包及Chunk哈希值最新
二、公网验证
2.1 确认浏览器加载包的信息
2.2 本地终端
2.3 CDN/代理层 忽略 no-cache 请求
2.3.1 作用:安全防御
2.3.2 解决“忽略请求头”的情况
2.3.3 总结
三、服务器:确认加载的包及chunk信息
一、本地:确定构建包及Chunk哈希值最新
# find:查找比特定文件更新的文件 find src -type f -newer paperless/index.html # 确认入口文件的指纹 grep -oE 'app\.[a-f0-9]+\.js' paperless/index.html # 查看 dist 目录下所有的 JS 包及其哈希值 ls -l dist/js/ | grep -E '\.js$' # 验证新内容是否在特定的包中 grep -c "portentry_agent_phone_" dist/js/app.71453325.js | wc -l grep -l 'join(",")' paperless/js/*.js二、公网验证
2.1 确认浏览器加载包的信息
# 获取页面加载的所有 JS 文件及其哈希值 performance.getEntriesByType('resource') .filter(r => /\.js$/.test(r.name)) .map(r => r.name.split('/').pop()) # 过滤出 app 包和 chunk 包 JSON.stringify({ origin: location.origin, js: performance.getEntriesByType('resource') .filter(r => /\.js$/.test(r.name)) .map(r => r.name.split('/').pop()) .filter(n => /^(app|chunk|[\d]+)\./.test(n)) }) # <"{\"origin\":\"https://gate.lswxdomain.com:20026\",\"js\":[\"app.85103410.js\",\"26.e1628011.js\",\"407.5954579c.js\",\"54.49aa8d3a.js\"]}" # 查看特定包(如 app.js)的哈希值 performance.getEntriesByType('resource') .filter(r => /app\.\w+\.js/.test(r.name)) .map(r => r.name.split('/').pop())2.2 本地终端
U=https://ip:port ## 用户操作 -> 页面获取 # 3.1. 查看服务器 index.html 当前引用的 app 包哈希(普通用户) curl -sk $U/index.html | grep -oE 'app\.[a-f0-9]+\.js' # 3.2. 强力绕过浏览器和代理缓存,直读服务器最新 index.html(绕过CDN/代理) echo "=== 服务器 index.html 带 cache-busting 直读 ===" curl -sk "$U/?nocache=$(date +%s)" | grep -oE 'app\.[a-f0-9]+\.js' # 3.3. 绕过nginx自身缓存 echo "=== 带 no-cache 请求头直读 ===" curl -sk -H 'Cache-Control: no-cache' "$U/" | grep -oE 'app\.[a-f0-9]+\.js' ################################################################################### # 验证某个特定的 chunk 包是否存在于服务器上(返回 HTTP 状态码) curl -sk -o /dev/null -w "%{http_code}\n" "$U/js/460.d9bbf1d7.js" # 验证服务器上的包是否包含新加的内容 curl -sk "$U/js/app.71453325.js" | grep -c "portentry_agent_phone_" # 查看服务器首页的响应头 curl -skI $U/ | grep -iE 'cache-control|last-modified|etag'2.3 CDN/代理层 忽略 no-cache 请求
动作:手动刷新(F5)时重新发送请求(带上Cache-Control: no-cache请求头( 同3.3))
2.3.1 作用:安全防御
DoS攻击(Denial of Service):黑客脚本以 万次/秒高频 向网站发起带有“Cache-Control:no-cache”请求,CDN将请求全部转发为源站服务器
所以为了防止DoS攻击,一些CDN(Cloudflare、阿里云、腾讯云),默认配置下会忽略客户端发送的 no-cache 请求头
2.3.2 解决“忽略请求头”的情况
第一种方式:不依赖客户端的请求头,通过修改源站的响应头(如no-store或文件哈希)来从根本上控制缓存。不允许客户端将文件存进自己的缓存。
扩展(第二种方式):使用专属的 CDN 控制头(如 Surrogate-Control)。比如顶级 CDN —— Fastly ,除了标准的Cache-Control,还支持Surrogate-Control响应头。这个头是专门给 CDN 看的,优先级极高,用来精确控制 CDN 的缓存行为,而不受客户端请求头的干扰。
2.3.3 总结
从请求头和响应头互相博弈的角度(排查服务端/网络层),理解为什么响应头做好设置为no-store策略:因为no-cache时,CDN可能会出现不问 或者 问错的情况。
原因:1. 某些不够严谨的 CDN 或代理层在处理时,优先响应客户端的请求头,而忽略源站下发的响应头。
2.no-cache的验证机制依赖的ETag(文件指纹:size and msize)或Last-Modified(修改时间)没有正确更新。
三、服务器:确认加载的包及chunk信息
# 容器的名称:容器基于的镜像 docker ps --format '{{}}\t{{}}' | grep -i nginx # root docker exec nginx nginx -T 2>/dev/null | grep -n -A6 'location \^~ /paperless/' # 指纹 docker exec nginx grep -oE 'app\.[a-f0-9]+\.js' /usr/share/nginx/html/paperless/index.html docker exec nginx ls -l /usr/share/nginx/html/paperless/index.html docker exec nginx ls /usr/share/nginx/html/paperless/js/ | sortsudo docker cp /data/nginx/html/paperless <NAME/PID>:/usr/share/nginx/html/
使用PID时,注意是否有多余的空格,隐藏字符+PID 会被当成一个全新的容器