微信 开发 图片 上传 阿里云 oss 服务器

在做微信开发时,我需要将图片上传至阿里云OSS,思路是服务端下载微信图片再转存至OSS。

wx.chooseImage({
  count: 1, // 默认9
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success: function (res) {
    var localIds = res.localIds;
    wx.uploadImage({
      localId: localIds[0], // 需要上传的图片的本地ID,由chooseImage接口获得
      isShowProgressTips: 1, // 默认为1,显示进度提示
      success: function (res) {
        var serverId = res.serverId; // 返回图片的服务器端ID
        // do something ...
        // 调用自己搭建的服务端的api,传入serverId,做获取微信图片上传OSS的相关操作
        doSomething();
      }
    });
  }
});

选择图片时只要选择了compressed,微信就会自动帮我们压缩图片,官方文档也说明上传的多媒体文件会控制格式和大小,其中图片控制在jpg格式和1M以下的大小。所以,基本不用考虑图片过大的问题。实测中,8M的图片压缩后只有120KB左右。

将图片先上传至微信的服务器(最多保存3天),再通过微信的下载多媒体文件接(http://file.api.weixin.qq.com…)将图片下载到服务器,再上传至OSS(虽然有点绕,但可行)。

主要有三种方法处理

1、利用fs将图片写到本地

const fs = require('fs');
const request = require('require');
const OSS = require('ali-oss').Wrapper;

const ossClient = new OSS({
  accessKeyId: 'your access key',
  accessKeySecret: 'your access secret',
  bucket: 'your bucket name',
  region: 'oss-cn-hangzhou'
});

// 需要获取微信accessToken,这里不细说
const accessToken = 'access token';
const mediaId = 'xxxxxxx'; // 微信多媒体文件id
const destPath = `weixin/images/201702/${mediaId}.jpg`; // OSS文件路径,按自己喜欢构造咯
const wxReq = request(`http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=${accessToken }&media_id=${mediaId}`);

// 将文件流pipe到本地文件
wxReq.pipe(fs.createWriteStream(`${mediaId}.jpg`));
wxReq.on('end', () => {
  co(function* () {
    const result = yield ossClient.putStream(destPath, fs.createReadStream(`${mediaId}.jpg`), {timeout: 30 * 60 * 1000});
    console.log('图片上传阿里云结果', result);
    fs.unlink(`${mediaId}.jpg`);
    // res.status(200).json(result);
  }).catch(err => {
    console.warn(err);
    //res.status(500).send('上传文件出错');
  });
});

这种方式需要频繁地写文件和删文件,很不友好。

2、利用memory-streams模块将图片写到内存

const request = require('require');
const OSS = require('ali-oss').Wrapper;
const streams = require('memory-streams');

const ossClient = new OSS({
  accessKeyId: 'your access key',
  accessKeySecret: 'your access secret',
  bucket: 'your bucket name',
  region: 'oss-cn-hangzhou'
});

const accessToken = 'access token';
const mediaId = 'xxxxxxx'; // 微信多媒体文件id
const destPath = `weixin/images/201702/${mediaId}.jpg`; // OSS文件路径
const writer = new streams.WritableStream();
const wxReq = request(`http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=${accessToken }&media_id=${mediaId}`);

wxReq.pipe(writer);
wxReq.on('end', () => {
  co(function* () {
    const result = yield ossClient.put(destPath, writer.toBuffer(), {timeout: 30 * 60 * 1000});
    console.log('图片上传阿里云结果', result);
    // res.status(200).json(result);
  }).catch(err => {
    console.warn(err);
    //res.status(500).send('上传文件出错');
  });
});

这种方式将图片暂存在内存里面,那如果并发量很大,服务器内存爆炸。

3、将下载图片的流直接写入OSS文件

const request = require('require');
const OSS = require('ali-oss').Wrapper;

const ossClient = new OSS({
  accessKeyId: 'your access key',
  accessKeySecret: 'your access secret',
  bucket: 'your bucket name',
  region: 'oss-cn-hangzhou'
});

const accessToken = 'access token';
const mediaId = 'xxxxxxx'; // 微信多媒体文件id
const destPath = `weixin/images/201702/${mediaId}.jpg`; // OSS文件路径
const wxReq = request(`http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=${accessToken }&media_id=${mediaId}`);

wxReq.on('response', (response) => {
  // request的响应结果response可以作为读取流传给ossClient
  co(function* () {
    const result = yield ossClient.putStream(destPath, response, {timeout: 30 * 60 * 1000});
    console.log('图片上传阿里云结果', result);
    // res.status(200).json(result);
  }).catch(err => {
    console.warn(err);
    //res.status(500).send('上传文件出错');
  });
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值