node.js - 由于 header 中的内容长度而导致代码 400 错误请求

标签 node.js http

我正在编写测试 RESTful api 的规范。我用来发出http请求的模块是standard http module在nodejs中。

如果我没有在 header 中指定“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();
        });
    });
});

最佳答案

在研究同样的问题时看到了你的帖子,我想我不妨根据我的发现发布一个答案,尽管距离你发布这篇文章已经过去了大约 2.5 年。不妨贡献一下,供以后引用。 :)

以下是一些要点:

首先,建议使用Buffer.byteLength(post_data)而不是变量的字符串长度来考虑不同的编码类型。

我已经在本地计算机上简化了您的代码,并尝试将其拍摄到我计划挖掘的本地工作站点上。删除内容长度给了我一个 411(需要长度)。然而,在保持大部分代码完好无损的情况下,我成功地使用 Content-Length 获取了一些结果。照原样。我的问题恰恰相反,我尝试将 GET 方法与 Content-Length 一起使用。 。这在目标服务器上不起作用。我的猜测是服务器的问题或者 RFC 的问题。这没关系,因为我见过的大多数实现仅在执行 POST 时而不是 GET 时使用它。

最后,我建议阅读 RFC for Content-Length以及 GET method以获得基本的了解。其规范有一些细微差别,但有些值得记住。

当我明白我的问题是什么时,值得注意的项目是这样说的:

对于 GET 方法:

A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.

在内容长度文档下我发现了这个:

..a Content-Length header field is normally sent in a POST request even when the value is 0 (indicating an empty payload body). A user agent SHOULD NOT send a Content-Length header field when the request message does not contain a payload body and the method semantics do not anticipate such a body. ... A sender MUST NOT send a Content-Length header field in any message that contains a Transfer-Encoding header field.

另外,这个site帮助我从浏览器中获取一些信息以及从服务器的角度来看它可能是什么样子。如果目标服务器在互联网上可见,您还可以使用它来调试目标服务器。

一个简单的检查服务器是否接受 GET 方法中的 Content-Length 的方法是将其值设置为零。测试 POST 时也是如此。

值得注意的是,HTTP/1.1 使用传输编码来消除内容长度的猜测,并且它们也不应该同时使用。 Node.js HTTP 文档在底部提到了这一点:

Sending a 'Content-Length' header will disable the default chunked encoding.

我建议您保持原样,不要使用 Content-Length。它应该在那里,所以你不必担心。

关于node.js - 由于 header 中的内容长度而导致代码 400 错误请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24596629/

相关文章:

javascript - 使用 NodeJS 创建 YouTube 播放列表

mysql - 在koa中使用mysql : co-mysql vs mysql-co?

node.js - 错误: Invalid login: 535 Authentication failed: Bad username/password with node mailer

scala - 我应该如何等待 scala dispatch (0.11.0) http get 请求完成?

javascript - jQuery 是否支持从 X-JSON HTTP header 读取 JSON?

node.js - 多个 2dsphere 索引,不确定要运行 geoNear 中的哪一个

node.js - keystone.js 当前登录的用户

http - 如何在不使用 golang 中的 ioutil.ReadAll 的情况下检索网站源

windows - HttpAddFragmentToCache 和操作系统错误 50

Java HTTP POST 请求字符串未到达