egg curl 微信上传素材

2019-05-16  本文已影响0人  吴占超

写在前边的话:
感谢阿里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);
});

感谢您看到了最后,谢谢!

上一篇下一篇

猜你喜欢

热点阅读