请教个关于Nodejs中Request Payload的问题
请教个关于Nodejs中Request Payload的问题
做项目要更新redmine的状态,一直不成功,贴出代码,求各位大神指导!
var hex = ‘zEpLAwrPVTS47stg’;
(var contents = getPayload([
{name: '_method', value: 'put'},
{name: ‘issue[subject]’, value: ‘标题’}, {name: ‘done_ratio’, value: ‘55’}, {name: ‘commit’, value: ‘提交’} ], hex);
var options = { host: this.host, port: this.port, path: ‘/redmine/issues/2223’, method: ‘post’, headers: { ‘Content-Length’: + contents.length, ‘Content-Type’: ‘multipart/form-data; boundary=----WebKitFormBoundar’ + hex, ‘Cookie’: session } };
send(options, contents, function (header, data) { console.log(data); });)();
function send(option, data, callback) { var req = http.request(option, function(res) { var resData = ‘’;
res.setEncoding(‘utf8’);
res.on(‘data’, function (chunk) { resData += chunk; });
res.on(‘end’, function () { callback && callback(res.headers, resData); }); });
data && req.write(data); req.end(); }
function getPayload(array, hex) { var data = ‘’;
array.forEach(function (elm, index) { data += (’------WebKitFormBoundary’ + hex + ‘\r\n’ + ‘Content-Disposition: form-data; name="’ + elm.name + ‘"’ + ‘\r\n\r\n’ + elm.value + ‘\r\n’); });
data += (’------WebKitFormBoundary’ + hex);
return data; }
好的,让我们来解答这个问题。你遇到的问题可能是由于 Content-Type
和 request payload
的格式不正确导致的。在发送 POST 请求时,确保 Content-Type
和请求体的数据格式一致非常重要。
问题分析
Content-Type
设置错误:你的代码中Content-Type
设置为multipart/form-data
,但是没有正确地生成 multipart 数据。- 边界符使用错误:
Content-Type
中使用的边界符需要在数据中正确地使用。
解决方案
我们需要正确地构建一个 multipart/form-data
请求体,并且确保 Content-Type
和请求体中的数据格式一致。
示例代码
const http = require('http');
// 生成请求体
function getPayload(array, hex) {
let data = '';
array.forEach(function (elm) {
data += ('------WebKitFormBoundary' + hex + '\r\n');
data += ('Content-Disposition: form-data; name="' + elm.name + '"\r\n\r\n');
data += (elm.value + '\r\n');
});
data += ('------WebKitFormBoundary' + hex + '--');
return data;
}
// 发送请求
function send(options, data, callback) {
const req = http.request(options, function (res) {
let resData = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
resData += chunk;
});
res.on('end', function () {
callback(res.headers, resData);
});
});
if (data) {
req.write(data);
}
req.end();
}
// 主函数
function updateRedmineIssue() {
var hex = 'zEpLAwrPVTS47stg';
var contents = getPayload([
{name: '_method', value: 'put'},
{name: 'issue[subject]', value: '标题'},
{name: 'done_ratio', value: '55'},
{name: 'commit', value: '提交'}
], hex);
var options = {
host: 'your.redmine.host',
port: 80,
path: '/redmine/issues/2223',
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(contents),
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary' + hex,
'Cookie': 'your-session-cookie'
}
};
send(options, contents, function (header, data) {
console.log(data);
});
}
updateRedmineIssue();
关键点解释
getPayload
函数:生成了正确的multipart/form-data
格式的数据。Content-Type
设置:确保与请求体中的数据格式一致。Content-Length
设置:根据实际请求体的长度动态设置。
通过以上修改,应该可以解决你遇到的问题。如果还有其他问题,请继续提供更多信息。
根据你的描述,你的问题主要涉及如何构建正确的请求体(Request Payload
)来更新 Redmine 中的 Issue 状态。当前代码中有一些问题需要修正,比如 Content-Type
的定义、生成边界字符串的方式以及请求体的格式。
以下是修正后的代码示例:
修改后的 getPayload
函数
function getPayload(array, hex) {
var boundary = '----WebKitFormBoundary' + hex;
var data = '';
array.forEach(function (elm, index) {
data += (
boundary + '\r\n' +
'Content-Disposition: form-data; name="' + elm.name + '"\r\n' +
'\r\n' +
elm.value + '\r\n'
);
});
data += (boundary + '--');
return data;
}
修改后的 options
对象
确保 Content-Type
的定义是正确的,并且不要忘记在 Content-Length
前加上正确的单位。
var options = {
host: this.host,
port: this.port,
path: '/redmine/issues/2223',
method: 'POST',
headers: {
'Content-Length': Buffer.byteLength(contents, 'utf8'),
'Content-Type': 'multipart/form-data; boundary=' + boundary,
'Cookie': session
}
};
调用 getPayload
函数
确保 hex
是一个随机生成的字符串,以确保每次请求时边界不同。
var hex = require('crypto').randomBytes(16).toString('hex');
var contents = getPayload([
{ name: '_method', value: 'put' },
{ name: 'issue[subject]', value: '新标题' },
{ name: 'done_ratio', value: '55' },
{ name: 'commit', value: '提交' }
], hex);
// 创建请求
var req = http.request(options, function (res) {
let resData = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
resData += chunk;
});
res.on('end', function () {
console.log(resData);
});
});
// 写入请求体
req.write(contents);
req.end();
总结
上述代码修正了 Content-Type
和 Content-Length
的设置,并且正确地构建了多部分表单数据。这样可以确保你的请求能够被 Redmine 正确解析。希望这可以帮助你解决遇到的问题。如果仍然有问题,请检查 Redmine 的 API 文档,确认是否需要其他额外的头信息或数据字段。