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

我试图把我的superagent post请求中的内容types发送给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); } }); 

我得到的错误是:TypeError:参数必须是一个string

如果我删除:

 .set('Content-Type', 'multipart/form-data') 

我没有得到任何错误,但我的后端接收请求作为内容types:application / json

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

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

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

目前还不清楚你发送的fieldsvariables是什么,但是这里有一些信息可以帮助你确定你的问题在哪里。

首先,如果您真的想要构build一个多部分的请求,这是这样做的官方文档: http : //visionmedia.github.com/superagent/#multipart-requests

至于你得到的错误…

原因是在准备请求的过程中,SuperAgent检查要发送的数据是否是string。 如果不是,则会尝试基于“Content-Type”的值序列化数据,如下所示:

 exports.serialize = { 'application/x-www-form-urlencoded': qs.stringify, 'application/json': JSON.stringify }; 

这是用在这里:

 // 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)); } } 

这意味着要手动设置一个表单“Content-Type”,你可以使用

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

要么

.type('form')像risyasin提到的那样

任何其他的“内容types”将不被序列化,并且Buffer.byteLength(data)将随后抛出TypeError: Argument must be a string如果fieldsvariables的值不是string,则TypeError: Argument must be a stringexception。

2017年 ,这样做。

首先,你不要提到以下任何一个:

 .set('Content-Type', 'multipart/form-data') 

要么

 .type('form') 

其次,你不使用.send ,你使用.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; }); 

而且,假设您想将JSON作为您的某个字段的值发送,那么您应该这样做。

 superagent .post( 'https://example.com/api/dog.crow' ) .accept('application/json') .field('data', JSON.stringify({ name: 'value' }) ) .then( ... ) .catch( ... ) 

刚刚失去了我这一生的岁月。 我不能让编程上帝喜欢它,但我做了一个工作黑客(我想运行一个AJAX请求,每次文件input更改更改):

<input type="file" onchange="handleInputChange()">

 import request from 'superagent'; handleInputChange = (event) => { console.log(event.target.files[0]); let fileObj = event.target.files[0]; let name = ''; let ext = ''; fileObj.name.split('.').map((val, index, arr) => { if (index === arr.length - 1) ext += val; else name += val; }); let size = fileObj.size; let type = fileObj.type; let reader = new FileReader(); reader.readAsDataURL(fileObj); reader.onloadend = function(e) { request.post('/api/project-image/') .set({ 'Accept': 'application/json' }) .send({ projectName: 'test', file: e.target.result.split(',').pop(), name: name, ext: ext, type: type, size: size }) .end(function(err, res) { if (err) { console.log(err); } else if (res) { const obj = assign({}, event); obj.field = props.field; obj.src = res.body.filename; obj.uid = props.uid; ActionCreator.editImage(obj); ActionCreator.toggleEditImage(obj); } }); }; }; 

这是为我工作。 我有一个单一的领域forms,即上传一个文件。 我把表单转换成了一个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 }); 

请注意,我尝试过用手动设置“Content-Type”的各种方法,并且由于Content-Type中需要的多部分标识符而无法正常工作。