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

从AWS服务器获取二进制文件转Uint8Array后长度异常求助

问题:从AWS获取二进制文件后,Uint8Array长度远大于返回的Content-Length?

我用以下TypeScript代码通过CapacitorHttp从AWS服务器获取二进制文件:

export const fetchBinaryFile = async(url: string): Promise<Uint8Array> => {
  try {
    const options: HttpOptions = {
      url,
      responseType: 'blob'
    };

    const response: HttpResponse = await CapacitorHttp.request(options);
    if (!response.data) {
      throw new Error('Failed to fetch binary file');
    }
    const blob = new Blob([response.data]);
    const arrayBuffer = await readBlobAsArrayBuffer(blob);
    const uint8Array = new Uint8Array(arrayBuffer);
    return uint8Array;
  } catch (error: any) {
    throw new Error(`Error: ${error.message}`);
  }
};

export const readBlobAsArrayBuffer = (blob: Blob): Promise<ArrayBuffer> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => {
      if (reader.readyState === FileReader.DONE) {
        console.log('resolve', reader.result);
        resolve(reader.result as ArrayBuffer);
      }
    };
    reader.onerror = reject;
   reader.readAsArrayBuffer(blob);
  });
};

请求返回的Content-Length是27852字节,但转换后的Uint8Array长度变成了37625字节,远大于原长度。我猜测是FileReader添加了元数据,但不确定原因,求解答。


原因分析

问题不是FileReader添加元数据,而是你错误地重新创建了Blob对象:

当你设置responseType: 'blob'时,CapacitorHttp返回的response.data本身已经是一个Blob实例。但你用new Blob([response.data])把它放进数组创建新Blob时,JavaScript会把数组里的Blob对象转换成UTF-8编码的字符串(因为Blob构造函数处理非二进制类型的参数时会默认按字符串处理),这个转换过程会破坏原二进制数据,导致长度膨胀。

解决方案

方案1:直接使用返回的Blob,无需重新创建

去掉多余的new Blob([response.data])步骤,直接用response.data作为Blob:

export const fetchBinaryFile = async(url: string): Promise<Uint8Array> => {
  try {
    const options: HttpOptions = {
      url,
      responseType: 'blob'
    };

    const response: HttpResponse = await CapacitorHttp.request(options);
    if (!response.data) {
      throw new Error('Failed to fetch binary file');
    }
    // 直接使用返回的Blob,不用重新创建
    const arrayBuffer = await readBlobAsArrayBuffer(response.data as Blob);
    const uint8Array = new Uint8Array(arrayBuffer);
    return uint8Array;
  } catch (error: any) {
    throw new Error(`Error: ${error.message}`);
  }
};

方案2:用Blob原生的arrayBuffer()方法替代FileReader

现代浏览器/环境中的Blob已经内置了arrayBuffer()方法,无需自己封装FileReader逻辑,代码更简洁:

export const fetchBinaryFile = async(url: string): Promise<Uint8Array> => {
  try {
    const options: HttpOptions = {
      url,
      responseType: 'blob'
    };

    const response: HttpResponse = await CapacitorHttp.request(options);
    if (!response.data) {
      throw new Error('Failed to fetch binary file');
    }
    // 直接调用Blob的arrayBuffer()方法
    const arrayBuffer = await (response.data as Blob).arrayBuffer();
    return new Uint8Array(arrayBuffer);
  } catch (error: any) {
    throw new Error(`Error: ${error.message}`);
  }
};

这样处理后,Uint8Array的长度就会和Content-Length一致了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:19:56