如何在 Node.js 请求中发布多个相同名称的值
Posted
技术标签:
【中文标题】如何在 Node.js 请求中发布多个相同名称的值【英文标题】:How to POST multiple values same name in Node.js Request 【发布时间】:2014-02-27 09:21:12 【问题描述】:我需要使用 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(',') 也不行
顺便说一句,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:与在支持 Request 方面做得很好的 Mikeal Rogers 聊天,他基本上说我不能在 Request 中这样做。由于我没有利用 Request 的许多很酷的特性,我将看看更基本的 http。
【问题讨论】:
您是仅使用 HTTP 还是使用 express 之类的模块? 【参考方案1】:偶然发现了这个问题,但从未使用 restler 让它工作。我确实发现它可以使用 npm 模块 'request' 就可以了
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。
【讨论】:
你是一个真正的生命救星,qsStringifyOptions: arrayFormat: 'repeat'
选项没有在任何地方记录,它就像一个魅力!
如果有人使用 request-promise qsStringifyOptions: arrayFormat: 'repeat'
到达这里,需要按照请求官方文档 github.com/request/request#requestoptions-callback 中所述的相同级别的 qs 传递
一年多过去了,这个解决方案仍然适用......它就像我一直在努力解决的问题的冠军一样。已经在使用 Request,但不知道 qsStringifyOptions 提供的完整选项变体。谢谢。
很高兴知道隐藏的宝石,qsStringifyOptions: arrayFormat: "brackets"
。在发送表单数据中的数组时很有用。
这节省了我的火炮测试!我需要调用一个 API,为同一个参数传递多个值,在 beforeRequest function 中添加 qsStringifyOptions 就可以了。【参考方案2】:
很抱歉回答我自己的问题,但万一其他人遇到这个问题......
迈克·罗杰斯当然是对的。 Request 使用 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 经验有限,所以这可能是错误的:-)
事实证明,node 的内置 querystring.stringify 做了我想要的,输出
foo=value0&foo=value1
快速破解是在Request.form()
中更改一行(大约是第 974 行)
this.body = *querystring*.stringify(form).toString('utf8')
但是,无论何时进行更新,您都必须记住再次执行此操作。不健壮。 “正确”的方法是子类化。我花了一段时间才找到一个小问题——你不能 require('request'),因为这会引入 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;
【讨论】:
如果有人像我一样偶然发现这一点,看起来 qs 现在有一个indices: false
选项可以禁用此行为。不确定这是否有用...
事实上,将请求中的qsStringifyOptions
和arrayFormat: repeat
结合起来,现在应该可以在不修改请求的情况下做到这一点。
谢谢,总有一天我会试一试的。
useQuerystring: true,这就是你现在所需要的。【参考方案3】:
var querystring = require('querystring');
var form =
//form parameters
request.post(http + querystring.stringify(form), callback);
在请求之外声明表单对象。然后,调用返回所需字符串的 querystring.stringify(form),并将该字符串附加到 url。以这种手动方式对 url 进行编码可以避免子类和更新问题。
【讨论】:
以上是关于如何在 Node.js 请求中发布多个相同名称的值的主要内容,如果未能解决你的问题,请参考以下文章
当您不知道页数时,如何使用 Node.js 在 while 循环中向 API 发出多个分页 GET 请求?
为啥在使用 Node.js 的许多文件中存在*** const 或 let 具有相同名称时,Typescript 会出错
如何从Google Cloud Function(Cheerio,Node.js)发出多个http请求