NodeJS 代码400错误请求,因为标题中的内容长度

zzwlnbp8  于 2023-05-28  发布在  Node.js
关注(0)|答案(1)|浏览(175)

我正在编写测试RESTful API的规范。我用来发出http请求的模块是nodejs中的standard http module
如果我没有在头中指定'Content-Length',那么请求成功,但我通过
options.headers['Content-Length'] = post_data.length;
,那么它是一个错误的请求,有400错误代码。我在stackoverflow中搜索内容长度相关的问题,但到目前为止没有灵感。我尝试了长度+1,只有100,都以同样的错误请求结束。
下面是我的代码。你能告诉我是什么问题吗?

var options = {
  hostname: hostname,
  port: port,
  headers: {
        'Content-Type': 'application/json',
        'Cache-Control': 'no-cache'
        // 'Content-Length': post_data.length
    }
};

describe('API Testing Function', function () {

    db.bind('user');

    describe('POST /api/user', function () {
        it('should return 400 when password is not present', function (done) {

            options.method = 'POST';
            options.path = '/api/user';
            var post_data = JSON.stringify({email:'111@email.com'});
            options.headers['Content-Length'] = post_data.length; // error here
            // if I delete above line, then it is totally good request. 

            var req = http.request(options, function(res){

                res.on('data', function(chunk){
                    // console.log('BODY:' + chunk);
                    var result = JSON.parse(chunk);
                    assert.equal(400, result.code);
                    done();
                });
            });
            req.write(post_data, 'utf8');
            req.end();
        });
    });
});
b5lpy0ml

b5lpy0ml1#

在研究同样的问题时偶然发现了你的帖子,我想我也可以根据我的发现发布一个答案,尽管你已经发布了大约2.5年了。不妨贡献一份,以备将来参考。:)
以下是一些要点:
首先,建议使用Buffer.byteLength(post_data)而不是变量的字符串长度来考虑不同的编码类型。
我已经在我的本地机器上简化了您的代码,并尝试将其与我计划采矿的本地工作站点进行比较。删除Content-Length给了我一个411(长度要求)。然而,在保留大部分代码的情况下,我设法用Content-Length提取了一些结果。我的问题是相反的,我试图使用GET方法沿着Content-Length。这在目标服务器上不起作用。我的猜测是这是一个服务器的事情或RFC的事情。这是可以的,因为我见过的大多数实现只在执行POST而不是GET时使用它。
最后,我建议阅读RFC中的Content-Length和GET方法,以获得基本的理解。它的规格有一些细微差别,但有些值得记住。
当我明白我的问题是什么时,值得注意的项目是这样说的:
对于GET方法:
GET请求消息中的有效载荷没有定义的语义;在GET请求上发送有效载荷主体可能导致一些现有实现拒绝该请求。
在Content-Length文档中,我发现了这个:
...内容长度报头字段通常在POST请求中发送,即使该值为0(指示空的有效载荷主体)。当请求消息不包含有效负载主体并且方法语义不预期这样的主体时,用户代理不应该发送内容长度报头字段。...发送方不得在任何包含传输编码报头字段的消息中发送内容长度报头字段。
此外,这个site帮助我从浏览器中获得了一些信息,以及从服务器的Angular 来看它可能是什么样子。如果目标服务器在Internet上可见,您也可以使用它来调试目标服务器。
如果服务器在GET方法中接受Content-Length,一个简单的检查是将其值设置为零。测试POST时也是如此。
值得注意的是,HTTP/1.1使用Transfer-Encoding来消除Content-Length中的猜测,并且它们也不应该同时使用。Node.js HTTP文档在底部提到了这一点:
发送'Content-Length'标头将禁用默认的分块编码。
我建议你保持原样,不要使用Content-Length。它应该在那里,所以你不必担心它。

相关问题