我需要使用node.js和Request以编程方式向POST提交多个值(在本例中为美国各州)。
例如,HTML表单可能是
<select name="stateprov[]" id="stateprov" multiple="multiple" >
后跟50个选项......,每个状态一个
提交的表单数据看起来像
stateprov%5B%5D=CA&stateprov%5B%5D=WI
如何使用请求执行此操作?鉴于我有一系列状态,['CA','WI'},我已经尝试了
form['stateprov[]'] = states
fails
it generates stateprov%5B%5D[0]=WI&stateprov%5B%5D[1]=CA as the output
form ['stateprov []'] = states.join(',')不起作用
BTW,Node人,我真的很喜欢这个项目,有很多很酷的东西,但你的文档不太好。后续:我认为问题可能是Request(https://npmjs.org/package/request)使用qs(https://npmjs.org/package/qs)对表单数据进行编码,并添加了无关的[0]和[1]。 Node内置的queryString(http://nodejs.org/api/querystring.html#querystring_querystring_stringify_obj_sep_eq)执行我想要的编码。
跟进#2:与Mikeal Rogers聊天,他在支持请求方面表现出色,他基本上说我不能在请求中这样做。由于我没有利用Request的许多很酷的功能,我会看一下更基本的http。
答案 0 :(得分:11)
偶然发现这个问题并且从未使用restler工作。我确实发现它使用npm模块&#39;请求&#39;只是做
import request from 'request';
let data = { subject: 'a message', recipients:['person1@gmail.com', 'person2@gmail.com'] }
// define your data above. I was having issues with the recipients needing to repeat
let options = {
form: data, qsStringifyOptions: {arrayFormat: 'repeat'}
}
request.post(url, options, function(err, res, body){
//callback. note request sends 3 params to callback
})
我把它包裹在Q库中以做出承诺。工作得很好。有点痛苦,因为我需要切换库,但希望这有助于soemone后来偶然发现。
答案 1 :(得分:1)
很抱歉回答我自己的问题,但万一其他人遇到这个问题...
迈克尔罗杰斯当然是对的。请求使用npm包qs(https://npmjs.org/package/qs)作为他的查询字符串解析器,无论好坏,当它“字符串化”一个数组时,它会添加'[n]'。function stringifyArray(arr, prefix) {
var ret = [];
if (!prefix) throw new TypeError('stringify expects an object');
for (var i = 0; i < arr.length; i++) {
ret.push(stringify(arr[i], prefix + '[' + i + ']')); <<< see here
}
return ret.join('&');
}
因此,具有多个值的表单将如下所示:
foo[0]=value0&foo[1]=value1
也许这就是你想要的,但它不是我想要的东西,这似乎与普通的HTML表单行为不匹配。我的HTML体验有限,所以这可能是错误的: - )
事实证明,querystring.stringify中内置的节点可以实现我想要的输出
foo=value0&foo=value1
快速破解是在Request.form()
(大约974行)中更改一行
this.body = *querystring*.stringify(form).toString('utf8')
但是,无论何时进行更新,您都必须记住再次执行此操作。不健壮。 “正确”的方式是子类。我花了一段时间才找到一个小问题 - 你不能要求('请求'),因为它带来了index.js,它导出了小写的工厂request()
方法。带有new
构造函数的“真实”大写字母位于request.js中。所以你必须具体:require('request/request.js')
以下是代码:(也在https://gist.github.com/MorganConrad/8827916)
var Request = require('request/request.js'); // IMPORTANT - specify request.js, don't get index.js!!!
var querystring = require('querystring');
MyRequest.prototype = Object.create(Request.prototype);
MyRequest.prototype.constructor = MyRequest;
function MyRequest(options, callbackfn) {
"use strict";
if (callbackfn)
options.callback = callbackfn;
options.method = options.method || 'POST';
Request.prototype.constructor.call(this, options);
}
MyRequest.prototype.form = function (form) {
"use strict";
if (form) {
this.setHeader('content-type', 'application/x-www-form-urlencoded; charset=utf-8');
this.body = querystring.stringify(form).toString('utf8');
return this;
}
else
return Request.prototype.form.apply(this, arguments);
};
module.exports = MyRequest;
答案 2 :(得分:-1)
var querystring = require('querystring');
var form = {
//form parameters
}
request.post(http + querystring.stringify(form), callback);
在请求之外声明表单对象。然后,调用querystring.stringify(form)返回所需的字符串,然后将该字符串附加到url。以手动方式编写URL以避免子类和更新问题。