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

如何让Service Worker返回带Transfer-Encoding: chunked头的响应?

问题分析与修正方案

一、请求头设置的错误点

  1. 错误设置CORS相关头:Access-Control-Allow-Origin和Access-Control-Allow-Credentials是服务器端用于跨域校验的响应头,手动在Service Worker中设置容易触发浏览器的CORS校验异常。如果字体请求是同域的,直接移除这两个头;如果是跨域场景,确保请求本身是合法的跨域类型后再考虑是否保留。

  2. Content-Encoding头不匹配:如果你的uint8Array是未压缩的原始TTF文件,却设置了Content-Encoding: gzip,浏览器会尝试用gzip解压内容,直接导致字体解析失败。若文件确实是gzip压缩的,要确认file是压缩后的二进制数据;否则直接删除这个头。

  3. 多余的传输层头:Transfer-Encoding: chunked、Date、Connection、Keep-Alive这些头由浏览器或底层传输层自动处理,手动设置不仅无效,还可能和浏览器默认行为冲突,全部移除即可。

  4. Cache-Control设置不合理:max-age=0会强制浏览器每次重新请求,若需要缓存字体,建议改成public, max-age=31536000(一年)这类合理值,按需调整。

修正后的请求头示例:

options.headers = new Headers({
  'Accept-Ranges': 'bytes',
  'Cache-Control': 'public, max-age=31536000',
  'Last-Modified': 'Thu, 23 May 2024 00:29:23 GMT',
  'Content-Type': 'font/ttf',
  'Vary': 'Accept-Encoding'
});

二、Response返回逻辑的问题

  1. 无需包装ReadableStream:已经拿到Uint8Array格式的文件,直接用它创建Response即可,额外包装Stream属于多余操作,还可能引发流处理异常。简化后的代码:
event.respondWith((async () => {
  const file = await readFile(path);
  if (destination === 'font') {
    return new Response(file, options);
  }
  // 补充非字体请求的默认处理,避免请求失败
  return fetch(event.request);
})());
  1. 缺少默认请求处理:原代码中如果destination不是font,没有返回任何内容,会导致非字体请求直接失败,必须补充默认的请求转发逻辑。

三、排查步骤

  1. 验证文件读取结果:在const file = await readFile(path);后添加console.log(file),确认返回的是正确的Uint8Array,且长度匹配字体文件的实际大小。
  2. 核对destination值:确认destination是从event.request.destination获取的,且拼写为小写的font。
  3. 查看浏览器调试信息:
    • 控制台检查是否有字体解析错误、CORS错误或Service Worker运行报错;
    • 网络面板查看字体请求的响应状态码、响应头、响应内容,若内容是乱码,大概率是Content-Encoding头设置错误导致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 14:07:19