如何使用node.js superagent发布multipart/form-data

nwk*_*ley 21 node.js superagent

我试图将我的superagent post请求中的内容类型发送到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);
    }
  });
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:TypeError:参数必须是一个字符串

如果我删除:

.set('Content-Type', 'multipart/form-data')
Run Code Online (Sandbox Code Playgroud)

我没有得到任何错误,但我的后端正在接收内容类型的请求:application/json

如何强制内容类型为multipart/form-data,以便我可以访问req.files()?

tre*_*der 21

2017年,这样做.

首先,您不要提及以下任何一项:

.set('Content-Type', 'multipart/form-data')
Run Code Online (Sandbox Code Playgroud)

要么

.type('form')
Run Code Online (Sandbox Code Playgroud)

其次,你不使用.send,你使用.field(name, value).

一个例子

假设您要发送带有以下内容的表单数据请求:

  • 两个文本字段:namephone
  • 一个文件: photo

所以你的请求将是这样的:

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;
  });
Run Code Online (Sandbox Code Playgroud)

而且,假设您想将JSON作为其中一个字段的值发送,那么您就是这样做的.

superagent
  .post( 'https://example.com/api/dog.crow' )
  .accept('application/json')

  .field('data', JSON.stringify({ name: 'value' })   )

  .then( ... )
  .catch( ... )
Run Code Online (Sandbox Code Playgroud)


ris*_*sin 14

尝试 .type('form') 而不是 .set('Content-Type', 'multipart/form-data')

http://visionmedia.github.io/superagent/#setting-the-content-type


Cha*_*ott 8

目前尚不清楚fields您发送的变量是什么,但这里有一些信息可以帮助您确定问题所在.

首先,如果您实际上是在尝试构建多部分请求,这是执行此操作的官方文档:http://visionmedia.github.com/superagent/#multipart-requests

至于你得到的错误......

原因是在准备请求的过程中,SuperAgent会检查要发送的数据以查看它是否为字符串.如果不是,它会尝试根据"Content-Type"的值序列化数据,如下所示:

exports.serialize = {
  'application/x-www-form-urlencoded': qs.stringify,
  'application/json': JSON.stringify
};
Run Code Online (Sandbox Code Playgroud)

在这里使用:

// 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));
  }
}
Run Code Online (Sandbox Code Playgroud)

这意味着要手动设置表单'Content-Type'

.set('Content-Type', 'application/x-www-form-urlencoded')

要么

.type('form')正如risyasin所说

任何其他'Content-Type'都不会被序列化,如果变量的值不是字符串,Buffer.byteLength(data)它将随后抛出TypeError: Argument must be a string异常 fields.