如何使用 node.js 超级代理发布多部分/表单数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13864983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to post multipart/form-data with node.js superagent
提问by nwkeeley
I am trying to send the content-type in my superagent post request to multipart/form-data.
我正在尝试将超级代理发布请求中的内容类型发送到 multipart/form-data。
var myagent = superagent.agent();
myagent
.post('http://localhost/endpoint')
.set('api_key', apikey)
.set('Content-Type', 'multipart/form-data')
.send(fields)
.end(function(error, response){
if(error) {
console.log("Error: " + error);
}
});
The error I get is: TypeError: Argument must be a string
我得到的错误是:TypeError: Argument must be a string
If I remove the:
如果我删除:
.set('Content-Type', 'multipart/form-data')
I don't get any error but my back end is receiving the request as content-type: application/json
我没有收到任何错误,但我的后端正在以内容类型接收请求:application/json
How can I force the content type to be multipart/form-data so that I can access req.files()?
如何强制内容类型为 multipart/form-data 以便我可以访问 req.files()?
回答by treecoder
First, you do not mention either of the following:
首先,您没有提及以下任何一项:
.set('Content-Type', 'multipart/form-data')
OR
或者
.type('form')
Second, you do not use the .send, you use .field(name, value).
其次,你不使用.send,你使用.field(name, value)。
Examples
例子
Let's say you wanted to send a form-data request with the following:
假设您想发送包含以下内容的表单数据请求:
- two text fields:
nameandphone - one file:
photo
- 两个文本字段:
name和phone - 一个文件:
photo
So your request will be something like this:
所以你的请求将是这样的:
superagent
.post( 'https://example.com/api/foo.bar' )
.set('Authorization', '...')
.accept('application/json')
.field('name', 'My name')
.field('phone', 'My phone')
.attach('photo', 'path/to/photo.gif')
.then((result) => {
// process the result here
})
.catch((err) => {
throw err;
});
And, let's say you wanted to send JSON as a value of one of your fields, then you'd do this.
而且,假设您想将 JSON 作为您的字段之一的值发送,然后您会这样做。
try {
await superagent
.post( 'https://example.com/api/dog.crow' )
.accept('application/json')
.field('data', JSON.stringify({ name: 'value' }))
}
catch ( ex ) {
// .catch() stuff
}
// .then() stuff...
回答by risyasin
Try
.type('form')instead of
.set('Content-Type', 'multipart/form-data')
尝试
.type('form')代替
.set('Content-Type', 'multipart/form-data')
See http://visionmedia.github.io/superagent/#setting-the-content-type
见http://visionmedia.github.io/superagent/#setting-the-content-type
回答by Chad
It is not clear what is in the fieldsvariable that you are sending, but here is some information that may help you determine where your problem lies.
不清楚fields您发送的变量中有什么,但这里有一些信息可以帮助您确定问题所在。
To begin with, if you are actually trying to build a multi-part request, this is the official documentation for doing so: http://visionmedia.github.com/superagent/#multipart-requests
首先,如果你真的想构建一个多部分请求,这是这样做的官方文档:http: //visionmedia.github.com/superagent/#multipart-requests
as for the error that you got...
至于你得到的错误......
The reason is that during the process of preparing the request, SuperAgent checks the data to be sent to see if it is a string. If it is not, it attempts to serialize the data based on the value of the 'Content-Type', as seen below:
原因是在准备请求的过程中,SuperAgent 会检查要发送的数据是否为字符串。如果不是,它会尝试根据“Content-Type”的值序列化数据,如下所示:
exports.serialize = {
'application/x-www-form-urlencoded': qs.stringify,
'application/json': JSON.stringify
};
which is used here:
在这里使用:
// body
if ('HEAD' != method && !req._headerSent) {
// serialize stuff
if ('string' != typeof data) {
var serialize = exports.serialize[req.getHeader('Content-Type')];
if (serialize) data = serialize(data);
}
// content-length
if (data && !req.getHeader('Content-Length')) {
this.set('Content-Length', Buffer.byteLength(data));
}
}
this means that to set a form 'Content-Type' manually you would use
这意味着要手动设置表单“Content-Type”,您将使用
.set('Content-Type', 'application/x-www-form-urlencoded')
.set('Content-Type', 'application/x-www-form-urlencoded')
or
或者
.type('form')as risyasinmentioned
.type('form')正如risyasin提到的
any other 'Content-Type' will not be serialized, and Buffer.byteLength(data)will subsequently throw the TypeError: Argument must be a stringexception if the value of your fieldsvariable is not a string.
任何其他“内容类型”都不会被序列化,如果您的变量的值不是字符串,Buffer.byteLength(data)则会随后抛出TypeError: Argument must be a string异常 fields。
回答by Burneh
Here is what worked for me. I had a single field form, that was uploading a file. I turned the form into a HTML5 FormData element and then did it as follows:
这对我有用。我有一个单字段表单,用于上传文件。我将表单转换为 HTML5 FormData 元素,然后按如下方式执行:
var frm = new FormData(document.getElementById('formId'));
var url = 'url/here';
superagent.post(url)
.attach('fieldInFormName', frm.get('fieldInFormName'))
.end( function (error, response) {
//handle response
});
Please note, I tried various ways of setting the 'Content-Type' manually in superagent, and it never worked correctly because of the multipart identifier needed in the Content-Type.
请注意,我尝试了各种在超级代理中手动设置“内容类型”的方法,但由于内容类型中需要多部分标识符,因此它从未正常工作。

