美文网首页
egg curl 微信上传素材

egg curl 微信上传素材

作者: 吴占超 | 来源:发表于2019-05-16 21:03 被阅读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);
    });
    

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

    相关文章

      网友评论

          本文标题:egg curl 微信上传素材

          本文链接:https://www.haomeiwen.com/subject/xdvwaqtx.html