Cloudflare Worker缓存GitHub资源时响应顺序异常问题排查
故障根因
缓存返回内容顺序错乱、渲染异常是两个代码逻辑错误共同触发的:
- 缓存键构造错误
你定义的cacheData对象错误携带了原请求的req.body属性:对于访问静态资源的GET请求本身不存在请求体,传入的req.body是一个不可重复读取的ReadableStream空引用,会导致Cache API计算缓存键时出现匹配紊乱,把不同资源(index.html、rocket.png、rocket2.png)的缓存内容和请求错配,出现请求A资源返回B资源内容的问题。 - 响应流读取竞态
fetch返回的Response对象的body是单次读取的ReadableStream,你直接把未克隆的响应对象传给cache.put同时后续还要把响应返回给用户时,缓存写入逻辑和响应返回逻辑会同时争抢读取同一个流,最终读出来的内容会出现截断、跨资源拼接、顺序错乱的问题。
另外你写入缓存时没有透传正确的Content-Type响应头,会导致浏览器无法按正确类型解析资源,进一步加剧渲染异常。
修复方案
按以下逻辑调整缓存代码即可:
- 构造缓存键时不要传入请求体,仅保留请求方法和URL即可,保证缓存键唯一匹配:
const cache = caches.default; // 构造稳定的缓存键,GET请求不要携带body参数 const cacheKey = new Request(req.url, { method: req.method });
- 缓存读取逻辑直接使用构造好的固定缓存键匹配:
const cachedResponse = await cache.match(cacheKey); if (cachedResponse) return cachedResponse;
- 拉取源站资源后,先克隆响应再写入缓存,避免流竞争,写入缓存操作放到后台执行不要阻塞响应返回:
// 拉取GitHub源站资源 const originResponse = await fetch(r.download_url); // 克隆响应实例,单独用于缓存写入,避免和返回给用户的响应抢读流 const cacheCopy = originResponse.clone(); // 后台异步写入缓存,不阻塞响应 event.waitUntil(cache.put(cacheKey, cacheCopy)); // 直接返回源站响应给用户 return originResponse;
如果需要自定义响应头(比如配置CORS、缓存时间),请基于源站响应的headers新建Response对象后再返回/写入缓存,不要直接修改原响应的头属性。
内容的提问来源于stack exchange,提问作者user16513519
相关产品推荐
相关产品推荐

