写在前边的话:
感谢阿里egg团队,感谢开源社区的大大们。感谢所有的为代码事业做贡献的人!
如果有问题,请查看github原文。
https://github.com/node-modules/urllib#api-doc
https://github.com/node-modules/formstream
最近在做微信小程序开发,使用了阿里系egg。采用curl进行httpclient请求。但是在项目中使用curl进行form提交(上传素材)时进行了各种尝试和资料的查找。终于成功解决了错误
errcode":41005,"errmsg":"media data missing
话不多说上代码:
const formstream = require('formstream');
/**
* 上传log图片只支持jpg 1mb以下
*
* @param {*} formData 表单数据
* @param {*} publicAccessToken 公众号 accesstoken
* @returns
* @memberof ApiWeiXin
*/
async uploadimg(formData, publicAccessToken) {
const url = `https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=${publicAccessToken}`;
const form = formstream();
form.buffer('media', formData.buffer.value, 'cardLogo.png', 'image/png');
return this.app.ctx.curl(url, {
method: 'POST',
headers: form.headers(),
stream: form,
dataType: 'json',
});
}
重点在于采用【formstream】由于我的图片采用base64方式上传获得,所以没有进行文件转存直接使用了form.buffer。也可以使用form.file
另附上调用及图片处理代码:
/**
* logo卡素材图片修改
*
* @returns
* @memberof SysCardSettingsService
*/
async cardLogo() {
const { ctx } = this;
const base64Data = ctx.request.body.content.replace(/^data:image\/\w+;base64,/, '');
const dataBuffer = Buffer.from(base64Data, 'base64');
const accessToken = await ctx.helper.ApiWeiXin.getAccessToken();
const formData = {
buffer: {
value: dataBuffer,
options: {
filename: 'cardLogo.png',
contentType: 'image/png',
},
},
};
const img = await ctx.helper.ApiWeiXin.uploadimg(formData, accessToken, ctx.request.body.content);
const imgUrl = img.data;
!ctx.mid && (ctx.mid = {});
ctx.mid.param = {
code: 'cardLogo',
key: 'cardLogo',
display: '会员卡Logo',
jsonValue: imgUrl,
result: img,
updateSysUserId: ctx.auth.id,
};
ctx.mid.where = {
code: 'cardLogo',
key: 'cardLogo',
};
const result = await this.findOrCreate();
!result[1] && result[0].update(ctx.mid.param);
return {
url: imgUrl.url,
isNew: result[1],
};
}
为何如此大费周章采用request调用一样可以实现效果啊:
const request = require('request');
async uploadimg(formData, publicAccessToken) {
const url = `https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=${publicAccessToken}`;
return new Promise((resolve, reject) => {
request.post(
{
url,
formData,
dataType: 'json',
},
function optionalCallback(err, httpResponse, body) {
if (err) {
reject(err);
}
resolve(body);
}
);
});
}
为了单元测试的mockHttpclient:
it('post /card-settings/card-logo', async () => {
app.mockHttpclient(/https:\/\/api.weixin.qq.com\/cgi\-bin\/media\/uploadimg\?access_token =[^]/, 'POST',
{
data: {
errcode: 0,
errmsg: 'ok',
url: 'http://mmbiz.qpic.cn/XXXXX',
},
});
const result = await app.httpRequest()
.post('/card-settings/card-logo')
.set('token', app.token)
.send({ content: 'base64:image' });
assert(result.status === 200);
const bodyKeys = _.keys(result.body);
const outKeys = _.keys(app.mockContext().rule.backgroundImgOut);
assert(_.difference(bodyKeys, outKeys).length === 0);
});
感谢您看到了最后,谢谢!
网友评论