如何使用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
目前还不清楚你发送的fields
variables是什么,但是这里有一些信息可以帮助你确定你的问题在哪里。
首先,如果您真的想要构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
如果fields
variables的值不是string,则TypeError: Argument must be a string
exception。
在2017年 ,这样做。
首先,你不要提到以下任何一个:
.set('Content-Type', 'multipart/form-data')
要么
.type('form')
其次,你不使用.send
,你使用.send
.field(name, value)
。
一个例子
比方说,你想发送一个表单数据请求与以下内容:
- 两个文本字段:
name
和phone
- 一个文件:
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中需要的多部分标识符而无法正常工作。