使用 Chai-HTTP 发布时似乎有错误的内容类型
Seem to Have the Wrong Content Type When POSTing with Chai-HTTP
我希望使用 Chai-HTTP 进行一些测试。当然,我想测试的不仅仅是我的 GET,但是我在尝试制作 POSTs 时似乎遇到了一个主要障碍。
为了找出我的 POST 无法正常工作的原因,我开始用 POST 测试服务器攻击它们。
这里是 POST 尝试使用完全不同的工具链(Jasmine-Node 和 Frisby)进行格式化以进行测试(效果很好):
frisby.create('LOGIN')
.post('http://posttestserver.com/post.php', {
grant_type:'password',
username:'helllo@world.com',
password:'password'
})
.addHeader("Token", "text/plain")
.expectStatus(200)
})
.toss();
这导致:
Time: Mon, 27 Jun 16 13:40:54 -0700
Source ip: 204.191.154.66
Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING =
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 19216
REMOTE_ADDR = 204.191.154.66
HTTP_CONNECTION = close
CONTENT_LENGTH = 64
HTTP_HOST = posttestserver.com
HTTP_TOKEN = text/plain
CONTENT_TYPE = application/x-www-form-urlencoded
UNIQUE_ID = V3GPVkBaMGUAAB1Uf04AAAAc
REQUEST_TIME_FLOAT = 1467060054.9575
REQUEST_TIME = 1467060054
Post Params:
key: 'grant_type' value: 'password'
key: 'username' value: 'hello@world.com'
key: 'password' value: 'password'
Empty post body.
Upload contains PUT data:
grant_type=password&username=hello%40world.com&password=password
这里是 POST 使用 Chai 和 Chai-HTTP 的尝试。我希望它能像上面使用 Jasmine 和 Frisby 的示例一样工作,但是,您会发现实际请求在几个方面有所不同。
describe('/post.php', function() {
var endPointUnderTest = '/post.php';
it('should return an auth token', function(done) {
chai.request('http://posttestserver.com')
.post(endPointUnderTest)
.set('Token', 'text/plain')
.send({
grant_type: 'password',
username: 'hello@world.com',
password: 'password'
})
.end(function(err, res) {
console.log(res);
res.should.have.status(200);
done();
});
});
});
这导致:
Time: Tue, 28 Jun 16 06:55:50 -0700
Source ip: 204.191.154.66
Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING =
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 1409
REMOTE_ADDR = 204.191.154.66
HTTP_CONNECTION = close
CONTENT_LENGTH = 76
CONTENT_TYPE = application/json
HTTP_TOKEN = text/plain
HTTP_USER_AGENT = node-superagent/2.0.0
HTTP_ACCEPT_ENCODING = gzip, deflate
HTTP_HOST = posttestserver.com
UNIQUE_ID = V3KB5kBaMGUAAErPF6IAAAAF
REQUEST_TIME_FLOAT = 1467122150.9125
REQUEST_TIME = 1467122150
No Post Params.
== Begin post body ==
{"grant_type":"password","username":"hello@world.com","password":"password"}
== End post body ==
Upload contains PUT data:
{"grant_type":"password","username":"hello@world.com","password":"password"}
请注意 CONTENT_TYPE、Post 参数和 PUT 数据的区别(我认为这是我问题的根源)。
Jasmine/Frisby 将使用 'application/x-www-form-urlencoded' 格式提交 POST,Chai-HTTP 似乎使用 'application/json' 格式。
我是否以某种方式滥用了 Chai-HTTP 的 POST 功能?还是 Chai-HTTP 不允许 'application/x-www-form-urlencoded' POST 请求?我似乎无法解决这个问题,这是我过渡到使用 Mocha/Chai 工具链进行测试的最后一个障碍(这是目标,我宁愿不使用不同的库,除非绝对必要)。
在 Chai-HTTP 的 Git-Hub 页面上进一步讨论了这个问题后,我发现这是 SuperAgent 的预期行为,Chai 引擎盖下的 HTTP 请求库- HTTP,它根据 .send() 调用中包含的数据类型自动检测内容类型。
我也偶然发现了 this particular question,这有助于阐明内容类型之间的实际区别。
如果其他人遇到这个问题,我了解到可以使用这样的调用很容易地更改 Chai-HTTP 的 POST 请求(感谢 meeber 的帮助 here):
//Override auto-detection by specifying the header explicitly
.set('content-type', 'application/x-www-form-urlencoded')
//Select the type 'form'
.type('form')
//Pass multiple strings in send instead of using an object
.send('grant_type=password')
.send('username=hello@world.com')
.send('password=password')
正在创建如下所示的请求:
describe('/post.php', function() {
var endPointUnderTest = '/post.php';
it('should return an auth token', function(done) {
chai.request('http://posttestserver.com')
.post(endPointUnderTest)
.set('Token', 'text/plain')
.set('content-type', 'application/x-www-form-urlencoded')
.type('form')
.send('grant_type=password')
.send('username=hello@world.com')
.send('password=password')
.end(function(err, res) {
console.log(res);
res.should.have.status(200);
done();
});
});
});
我希望使用 Chai-HTTP 进行一些测试。当然,我想测试的不仅仅是我的 GET,但是我在尝试制作 POSTs 时似乎遇到了一个主要障碍。
为了找出我的 POST 无法正常工作的原因,我开始用 POST 测试服务器攻击它们。
这里是 POST 尝试使用完全不同的工具链(Jasmine-Node 和 Frisby)进行格式化以进行测试(效果很好):
frisby.create('LOGIN')
.post('http://posttestserver.com/post.php', {
grant_type:'password',
username:'helllo@world.com',
password:'password'
})
.addHeader("Token", "text/plain")
.expectStatus(200)
})
.toss();
这导致:
Time: Mon, 27 Jun 16 13:40:54 -0700
Source ip: 204.191.154.66
Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING =
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 19216
REMOTE_ADDR = 204.191.154.66
HTTP_CONNECTION = close
CONTENT_LENGTH = 64
HTTP_HOST = posttestserver.com
HTTP_TOKEN = text/plain
CONTENT_TYPE = application/x-www-form-urlencoded
UNIQUE_ID = V3GPVkBaMGUAAB1Uf04AAAAc
REQUEST_TIME_FLOAT = 1467060054.9575
REQUEST_TIME = 1467060054
Post Params:
key: 'grant_type' value: 'password'
key: 'username' value: 'hello@world.com'
key: 'password' value: 'password'
Empty post body.
Upload contains PUT data:
grant_type=password&username=hello%40world.com&password=password
这里是 POST 使用 Chai 和 Chai-HTTP 的尝试。我希望它能像上面使用 Jasmine 和 Frisby 的示例一样工作,但是,您会发现实际请求在几个方面有所不同。
describe('/post.php', function() {
var endPointUnderTest = '/post.php';
it('should return an auth token', function(done) {
chai.request('http://posttestserver.com')
.post(endPointUnderTest)
.set('Token', 'text/plain')
.send({
grant_type: 'password',
username: 'hello@world.com',
password: 'password'
})
.end(function(err, res) {
console.log(res);
res.should.have.status(200);
done();
});
});
});
这导致:
Time: Tue, 28 Jun 16 06:55:50 -0700
Source ip: 204.191.154.66
Headers (Some may be inserted by server)
REQUEST_URI = /post.php
QUERY_STRING =
REQUEST_METHOD = POST
GATEWAY_INTERFACE = CGI/1.1
REMOTE_PORT = 1409
REMOTE_ADDR = 204.191.154.66
HTTP_CONNECTION = close
CONTENT_LENGTH = 76
CONTENT_TYPE = application/json
HTTP_TOKEN = text/plain
HTTP_USER_AGENT = node-superagent/2.0.0
HTTP_ACCEPT_ENCODING = gzip, deflate
HTTP_HOST = posttestserver.com
UNIQUE_ID = V3KB5kBaMGUAAErPF6IAAAAF
REQUEST_TIME_FLOAT = 1467122150.9125
REQUEST_TIME = 1467122150
No Post Params.
== Begin post body ==
{"grant_type":"password","username":"hello@world.com","password":"password"}
== End post body ==
Upload contains PUT data:
{"grant_type":"password","username":"hello@world.com","password":"password"}
请注意 CONTENT_TYPE、Post 参数和 PUT 数据的区别(我认为这是我问题的根源)。
Jasmine/Frisby 将使用 'application/x-www-form-urlencoded' 格式提交 POST,Chai-HTTP 似乎使用 'application/json' 格式。
我是否以某种方式滥用了 Chai-HTTP 的 POST 功能?还是 Chai-HTTP 不允许 'application/x-www-form-urlencoded' POST 请求?我似乎无法解决这个问题,这是我过渡到使用 Mocha/Chai 工具链进行测试的最后一个障碍(这是目标,我宁愿不使用不同的库,除非绝对必要)。
在 Chai-HTTP 的 Git-Hub 页面上进一步讨论了这个问题后,我发现这是 SuperAgent 的预期行为,Chai 引擎盖下的 HTTP 请求库- HTTP,它根据 .send() 调用中包含的数据类型自动检测内容类型。
我也偶然发现了 this particular question,这有助于阐明内容类型之间的实际区别。
如果其他人遇到这个问题,我了解到可以使用这样的调用很容易地更改 Chai-HTTP 的 POST 请求(感谢 meeber 的帮助 here):
//Override auto-detection by specifying the header explicitly
.set('content-type', 'application/x-www-form-urlencoded')
//Select the type 'form'
.type('form')
//Pass multiple strings in send instead of using an object
.send('grant_type=password')
.send('username=hello@world.com')
.send('password=password')
正在创建如下所示的请求:
describe('/post.php', function() {
var endPointUnderTest = '/post.php';
it('should return an auth token', function(done) {
chai.request('http://posttestserver.com')
.post(endPointUnderTest)
.set('Token', 'text/plain')
.set('content-type', 'application/x-www-form-urlencoded')
.type('form')
.send('grant_type=password')
.send('username=hello@world.com')
.send('password=password')
.end(function(err, res) {
console.log(res);
res.should.have.status(200);
done();
});
});
});