遇到 HTTP 411 Length Required 报错

October 26, 2020

目的

在 Node.js 中使用 axios 转发请求

遇到问题

在项目中使用别人封装的 http 请求, 启动报错, 返回状态码 HTTP 411

代码

部分伪代码

// ... 省略其他设置
axios({
    method: req.method.toLowerCase(),
    url,
    params: req.query,
    data: req.body,
    timeout: 600 * 1000,
    withCredentials: true,
})

问题分析

查询资料可以了解到状态码 411 对应的文本是 Length Required. 意思是请求头中没有定义 Content-Length 字段.

这个字段用于描述请求中 body 的长度, 但是当前场景下我使用的是 get 请求, 没有 body. 而且长度一般是由请求客户端自动设置的.

那就可以缩小排查范围, 思路:

  1. axios 这个包出了问题
  2. 对 axios 的使用出了问题

为验证第一点, 手动写了一个 axios 的原生请求, 代码如下

axios({
    method: 'get',
    url,
})

发现可以正常使用, 那么可以确定问题出在第二点

调试

自己编写可以跑通就清晰了, 其他人写的代码出了问题. 开始调试. 一共不到 20 行代码, 为了搞清楚哪一行出了问题, 采用二分法调试.

注释掉多余的请求设置, 发现可以跑通.

逐步放开设置, 直到发现有一个设置添加后会报错. 就是 data: req.body 这一行.

仔细一想就明白了, 这个请求封装方法, 全部设置了 body 中的data, get 请求时一般没有 data, axios 内部也没有设置 Content-Length 字段, 于是报错了.

解决方案也比较简单. 当 get 请求时, 不添加这个 data 属性

复现

可以从最小的 axios 请求开始复现这个问题, 在请求参数中加个 data 为空对象即可:

axios({
    method: 'get',
    url,
    data: {},
})

参考链接:


Profile picture

Written by xiaohai who lives and works in ShenZhen, building useful things.