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

Chromium浏览器Range请求是否存在分片大小限制?如何解决

问题场景

通过Range请求分片拉取服务端大体积3D模型文件,所有分片下载完成后拼接为完整ArrayBuffer,传入Cesium完成模型加载,核心实现代码如下:

const m = 1024 * 1024 * 3;
Axios({
  url: option.url,
  method: 'head'
}).then((res) => {
  const size = Number(res.headers['content-length']);
  const length = parseInt(size / m);
  const arr = []
  for (let i = 0; i < length; i++) {
      let start = i * m;
      let end = (i == length - 1) ?  size - 1  : (i + 1) * m - 1;
      arr.push(this.downloadRange(option.url, start, end, i))
  }
  Promise.all(arr).then(res => {
    const arrBufferList = res.sort(item => item.i - item.i).map(item => new Uint8Array(item.buffer));
    const allBuffer = this.concatenate(Uint8Array, arrBufferList);
    primitive = viewer.scene.primitives.add(
      new Cesium.Model({
        gltf: allBuffer,
        show: true,
        modelMatrix: modelMatrix,
        scale: parseFloat(option.scale) || 1,
      })
    );
  })
})

分片下载方法downloadRange实现如下:

downloadRange(url, start, end, i) {
  return new Promise((resolve, reject) => {
    const req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.setRequestHeader("range", `bytes=${start}-${end}`);
    req.responseType = "blob";
    req.onload = function (oEvent) {
      req.response.arrayBuffer().then((res) => {
        resolve({
          i,
          buffer: res,
        });
      });
    };
    req.send();
  });
}
异常表现
  • 分片参数m设置为小于6MB(即1024*1024*6)时,所有请求正常返回,流程无异常
  • 分片大小m超过6MB阈值时,浏览器抛出GET <url> net::ERR_FAILED 206 (Partial Content)错误,请求直接失败
  • Postman调用同接口请求30MB大小的分片可正常返回,可排除服务端Range支持故障
  • 异常在Chrome、Edge等Chromium内核浏览器可稳定复现
问题根因

该异常和Chromium内核本身的Range请求大小限制无关,核心诱因有两点:

  1. 实现逻辑中使用Promise.all一次性发起全部分片请求,没有做并发控制。Chromium内核默认对同域名下的普通请求设置6个左右的并发连接上限,针对响应体体积超过5MB的大体积请求,为了管控标签页内存占用,允许的并发数会进一步降低到2-3个,超出并发阈值的请求会被浏览器直接拦截抛出ERR_FAILED,根本不会发送到服务端。
  2. 代码中使用XHR接收Blob类型响应,需要等整个分片响应完全接收完成后才会生成Blob对象、进一步转ArrayBuffer,当分片体积超过6MB时,Chromium的Blob存储机制会触发单Blob内存阈值校验,瞬时内存占用过高时会直接中断请求。

Postman作为独立桌面应用,没有浏览器的并发连接限制、沙箱内存配额限制,因此大分片请求可以正常返回。

规避方案
  • 优先使用Cesium原生加载能力:直接将模型资源URL传入Cesium.Model构造函数,Cesium内部已实现成熟的大模型流式Range加载逻辑,自带并发控制、缓存、断点续传能力,稳定性和加载性能远高于手动实现的分片逻辑。
  • 添加并发控制:如果必须手动分片,不要用Promise.all一次性发起所有请求,实现简单的请求并发池,将同时间进行的分片请求数控制在2-3个,完成一个再发起下一个,避免触发浏览器并发管控阈值。
  • 调整分片大小:将单分片大小固定在4-5MB区间,这个区间是Chromium内核下验证过的安全阈值,既不会产生过多请求开销,也不会触发大响应的内存拦截机制。
  • 替换请求实现:将XHR+Blob的实现替换为Fetch API的流式读取,通过response.body.getReader()边接收边写入缓冲区,不需要等待整个响应生成Blob,可绕过单Blob的内存阈值限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:45:19