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

如何让axios读取超出Content-length长度的完整HTTP响应体

原因说明

你猜测的逻辑是正确的,响应体截断是Node.js内置http/https模块的默认行为:只要响应头携带Content-Length字段,模块只会读取对应字节数就触发流的end事件,超出部分会被直接丢弃,和上层axios逻辑无关。

解决方案

关闭Content-Length严格校验即可,核心是给底层HTTP请求传递strictContentLength: false参数,按你的技术栈给出两种实现方式:

方案1:继续使用axios,自定义适配器透传参数

import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import * as http from 'http';
import * as https from 'https';
import { Stream } from 'stream';

// 自定义适配,核心是新增strictContentLength参数关闭校验
const customAdapter = (config: AxiosRequestConfig): Promise<AxiosResponse> => {
  return new Promise((resolve, reject) => {
    const transport = config.url?.startsWith('https') ? https : http;
    const req = transport.request({
      ...config,
      strictContentLength: false,
    }, (res) => {
      resolve({
        data: res,
        status: res.statusCode,
        statusText: res.statusMessage,
        headers: res.headers,
        config,
        request: req,
      });
    });
    req.on('error', reject);
    if (config.data) req.write(config.data);
    req.end();
  });
};

// 你的原有axios配置新增adapter字段即可
const config: AxiosRequestConfig = {
  method: 'GET',
  url: 'https://替换为你的请求地址',
  headers: {
    Cookie: 'VerySecretCookie',
  },
  responseType: 'stream',
  maxRedirects: 0,
  decompress: false,
  timeout: 60000,
  adapter: customAdapter,
  rejectUnauthorized: false, // 对应curl的-k参数,需要忽略证书校验可保留,不需要可删除
};

// 原有流转换逻辑可以复用,仅建议新增toString避免Buffer拼接异常
private async streamToString(stream: Stream): Promise<string> {
  return new Promise((res, rej) => {
    let data = '';
    stream.on('end', () => res(data));
    stream.on('error', (err) => rej(err));
    stream.on('data', (chunk) => data += chunk.toString());
  });
}

// 调用逻辑不变
const response = await axios(config);
const fullData = await this.streamToString(response.data);

方案2:无需axios,直接用原生HTTP模块实现

如果没有强依赖axios的其他能力,直接用原生模块代码更精简:

import * as https from 'https';
import { Stream } from 'stream';

private async streamToString(stream: Stream): Promise<string> {
  return new Promise((res, rej) => {
    let data = '';
    stream.on('end', () => res(data));
    stream.on('error', (err) => rej(err));
    stream.on('data', (chunk) => data += chunk.toString());
  });
}

const fullData = await new Promise((resolve, reject) => {
  const req = https.request({
    hostname: '替换为你的域名',
    path: '替换为你的请求路径',
    method: 'GET',
    headers: {
      Cookie: 'VerySecretCookie',
    },
    rejectUnauthorized: false,
    strictContentLength: false,
  }, async (res) => {
    try {
      const data = await streamToString(res);
      resolve(data);
    } catch (e) {
      reject(e);
    }
  });
  req.on('error', reject);
  req.end();
});

注意事项

  • strictContentLength参数支持Node.js 12.19.0、14.5.0及以上版本,如果你使用的Node版本低于要求,可在收到响应头时手动删除res.headers['content-length'],也能达到相同效果。
  • 该方案仅适配你提到的未启用HTTP Keep-Alive的场景,如果开启了Keep-Alive,连接不会在单次请求结束后断开,可能会读到后续请求的响应内容,导致数据异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 23:18:02