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

如何使用Axios获取GET请求含请求头的完整大小

解决方案

首先明确:你无法通过修改客户端请求配置让服务端放弃分块传输、返回Content-Length头。Transfer-Encoding: chunked是服务端的传输策略,当响应体大小在响应发送前无法确定时,服务端就会采用分块编码,不会提前返回总长度,客户端没有权限修改这个服务端行为。

要统计包含请求头、请求体、响应头、响应体在内的完整流量大小,只能通过实际统计收发字节的方式实现,以下是Node.js环境下可直接运行的实现(浏览器端受Web API安全限制,无法拿到字节级精确的原始流量大小,只能获取解压后响应体的近似值)。

第一步:修正错误请求头

你当前代码里给GET请求加Content-Encoding: gzip是无效配置,这个头用于标记请求/响应体的编码格式,GET请求默认没有请求体,加这个头反而可能触发服务端异常,直接删掉即可。

第二步:字节级流量统计实现

通过axios拦截器+流处理,分别统计请求行、请求头、请求体、响应行、响应头、分块响应体的字节数,累加得到总大小:

const axios = require('axios');
const { PassThrough } = require('stream');

async function calcRequestTotalSize(url, customConfig = {}) {
  let totalBytes = 0;
  const reqInstance = axios.create({
    ...customConfig,
    responseType: 'stream',
    // 设为false则统计gzip压缩后的实际传输字节,设为true统计解压后的业务字节
    decompress: true
  });

  // 统计请求侧字节
  reqInstance.interceptors.request.use(config => {
    // 计算请求行长度 例:GET /api/v9/experiments HTTP/1.1\r\n
    const reqUrl = new URL(config.url, config.baseURL);
    const requestLine = `${config.method.toUpperCase()} ${reqUrl.pathname}${reqUrl.search} HTTP/1.1\r\n`;
    totalBytes += Buffer.byteLength(requestLine);

    // 计算请求头长度
    Object.entries(config.headers).forEach(([key, val]) => {
      totalBytes += Buffer.byteLength(`${key}: ${val}\r\n`);
    });
    totalBytes += Buffer.byteLength('\r\n'); // 头和体的分隔空行

    // 计算请求体长度(GET请求无请求体时自动跳过)
    if (config.data) {
      const bodyContent = typeof config.data === 'string' ? config.data : JSON.stringify(config.data);
      totalBytes += Buffer.byteLength(bodyContent);
    }
    return config;
  });

  const res = await reqInstance.get(url, {
    headers: {
      "Accept-Encoding": "gzip",
      "x-accept-encoding": "gzip"
    }
  });

  // 统计响应侧头字节
  const statusLine = `HTTP/${res.res.httpVersion} ${res.status} ${res.statusText}\r\n`;
  totalBytes += Buffer.byteLength(statusLine);
  Object.entries(res.res.headers).forEach(([key, val]) => {
    totalBytes += Buffer.byteLength(`${key}: ${val}\r\n`);
  });
  totalBytes += Buffer.byteLength('\r\n');

  // 逐块统计分块响应体字节
  return new Promise((resolve, reject) => {
    const counter = new PassThrough();
    res.data.pipe(counter);
    counter.on('data', chunk => totalBytes += chunk.length);
    counter.on('end', () => resolve(totalBytes));
    counter.on('error', reject);
  });
}

// 调用示例
calcRequestTotalSize("https://discord.com/api/v9/experiments").then(size => {
  console.log(`完整请求总大小(字节): ${size}`);
})

注意事项

  • 如果你要统计真实网络传输的流量消耗,把配置项decompress设为false,此时统计的是gzip压缩后的实际传输字节,和网卡层面统计的流量值一致
  • 分块传输的响应体不存在预计算的总长度,所有声称可以不接收完整响应就拿到大小的方法都是不可靠的
  • 不要尝试手动给请求添加Content-Length头修改传输编码,这个头是服务端生成响应时填写的,客户端强行设置不会改变服务端行为,反而会导致请求校验失败
  • 浏览器端受同源策略和Web API限制,无法获取原始请求/响应头的精确字节长度,也无法区分压缩前后的流量差,只能拿到解压后响应体的长度,做不到精确的流量统计。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:31:00