微信小程序上传图片到七牛云,小程序Webview嵌入H5上传图片&原生小程序上传图片
最近在帮朋友做微信小程序,没有选择mpvue,因为时间紧加上不熟悉,怕遇到坑不能快速处理,拖了进度,所以采用了原生小程序+webview的方式做了第一版。
小程序webview上传图片 因为涉及到H5,所以图片上传这块就用到了微信中的jssdk,
第一步是wx.config配置 前端代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 abp.services.app.wxAccess.getOfficialAccountJsdkConfig().done(function (data) { if (data) { var appId = data.appId; var timestamp = data.timestamp; var nonceStr = data.noncestr; var signature = data.signature; wx.config({ debug: false, //调试模式 当为tru时,开启调试模式 appId: appId, timestamp: timestamp.toString(), //签名时间戳 nonceStr: nonceStr, //生成签名的随机串 signature: signature, //签名 jsApiList: ['chooseImage', 'uploadImage'], success: function () { alert("配置成功"); }, fail: function () { alert("配置失败"); } }); wx.ready(function () { // 在这里调用 API wx.checkJsApi({ jsApiList: [ 'chooseImage', 'uploadImage' ], success: function (res) { //console.log(JSON.stringify(res)); } }); }); wx.error(function(res){ alert(JSON.stringify(res)); }); } });
后端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 /// <summary> /// 获取公众号JsdkConfig /// </summary> /// <returns></returns> public async Task<Dtos.GetOfficialAccountJsdkConfigOutput> GetOfficialAccountJsdkConfig() { var input = new Dtos.GetAccessInput { AppId = _appConfiguration["WechatOfficialAccount:AppId"], Secret = _appConfiguration["WechatOfficialAccount:Secret"] }; var noncestr = Guid.NewGuid().ToString("N"); var jsapi = await GetJsapiTicket(input); //var timestamp = (DateTime.Now.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks) / 10000000; var timestamp = new Helper.UnixTime().DateTimeToUnix(DateTime.Now); //var url = Request.UrlReferrer.OriginalString; var url = _iHttpContextAccessor.HttpContext.Request.Headers[Microsoft.Net.Http.Headers.HeaderNames.Referer].ToString(); var shaStr = $"jsapi_ticket={jsapi.Permit}&noncestr={noncestr}×tamp={timestamp}&url={url}"; var signature = new Helper.Encrypt().Sha1Encrypt(shaStr); return new Dtos.GetOfficialAccountJsdkConfigOutput { AppId = input.AppId, Noncestr = noncestr, Timestamp = timestamp, Signature = signature }; }
第二步就是调用jssdk 前端js代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 wx.chooseImage({ count: 9, needResult: 1, sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (data) { //localIds = data.localIds[0]; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片 for (var localId = 0; localId <= data.localIds.length - 1; localId++) { if (isIOS) { wx.getLocalImgData({ localId: data.localIds[localId], // 图片的localID success: function (res) { // var localData = res.localData; // localData是图片的base64数据,可以用img标签显示 //console.log(localData); } }); } else { } } }, fail: function (res) { alert(JSON.stringify(res)); //alterShowMessage("操作提示", JSON.stringify(res), "1", "确定", "", "", ""); } });
jssdk中,如果是iOS的话,前端无法直接使用localIds资源id做展示,需要调用wx.getLocalImgData方法来获取图片的base64编码
提交前端选择的图片到服务端并由服务的上传到七牛云 前端部分代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 wx.uploadImage({ //获取图片媒体ID localId: localIds[erp.common.idx].toString(), // 需要上传的图片的本地ID isShowProgressTips: 1, // 默认为1,显示进度提示 success: function (res) { //获取成功 // 上传序号,上传一张 累计 +1 erp.common.idx++; //存储图片媒体ID,用,号分割 // serverIds += res.serverId + ','; erp.common.serverIdsArr.push(res.serverId); if (erp.common.idx < localIds.length) { //本地图片ID 还没全部获取完图片媒体ID //调用上传递归函数 erp.common.wxUploadImg(localIds, callback); } else { //上传序号归零 erp.common.idx = 0; //服务器csrf 验证字符串,如果后端框架没开启csrf,则不需要 //alert(erp.common.serverIdsArr); abp.services.app.wxAccess.uploadMediaToQiniu({ WxMediaIds: mediaIds }).done(function (data) { var imageUrl = []; for (var index = 0; index <= data.qiniuFiles.length - 1; index++) { imageUrl.push(data.qiniuFiles[index].qiniuUrl); } $.hideLoading(); callback && callback(imageUrl); }).always(function(){ $.hideLoading(); }); //serverIds = ''; erp.common.serverIdsArr.length = 0; return true; } }, fail: function (res) { //获取多媒体id失败 返回错误代码 alert("上传失败,msg:" + JSON.stringify(res)); } });
后端部分代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /// <summary> /// 上传文件到七牛 /// </summary> /// <param name="input"></param> /// <returns></returns> //[RemoteService(false)] public async Task<Dtos.UploadMediaToQiniuOutput> UploadMediaToQiniu(Dtos.UploadMediaToQiniuInput input) { var output = new Dtos.UploadMediaToQiniuOutput(); if (input.WxMediaIds.Count > 0) { output.QiniuFiles = new System.Collections.Generic.List<Dtos.QiniuFile>(); var access_token = await GetOfficialAccountAccessToken(); var accessKey = _appConfiguration["Qny:qiniuyunAK"]; var secretKey = _appConfiguration["Qny:qiniuyunSK"]; var bucket = _appConfiguration["Qny:qiniuyunBucket"]; var prefixPath = _appConfiguration["Qny:prefixPath"]; var qiniuStorage = new Helper.QiniuStorage(accessKey, secretKey, bucket); foreach (var mediaId in input.WxMediaIds) { var url = $"https://api.weixin.qq.com/cgi-bin/media/get?access_token={access_token.Permit}&media_id={mediaId}"; var fileKey = qiniuStorage.UploadStream(url); var fileUrl = $"{prefixPath}/{fileKey}"; output.QiniuFiles.Add(new Dtos.QiniuFile { QiniuUrl = fileUrl, WxMediaId = mediaId }); } } return output; }
原生小程序上传图片到七牛云 后面考虑到一些交互上面的问题,就把原来的webview方式改成了全原生的模式。采用原生的方式,在图片上传上面就好处理多了,只需要实现获取到七牛云用于上传的token,然后使用wx.uploadFile即可上传。 服务端获取token代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 /// <summary> /// 获取七牛token /// </summary> /// <returns></returns> public QiniuTokenOutputDto GetQiniuUpToken() { var accessKey = _appConfiguration["Qny:qiniuyunAK"]; var secretKey = _appConfiguration["Qny:qiniuyunSK"]; var bucket = _appConfiguration["Qny:qiniuyunBucket"]; var qiniuStorage = new Helper.QiniuStorage(accessKey, secretKey, bucket); var output = new QiniuTokenOutputDto() { UpToken = qiniuStorage.CreateUploadToken() }; return output; }
小程序端部分代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 1、获取token 2、调用小程序API,选择图片。 wx.chooseImage({ count: 9-this.data.cardImgList.length, //默认9 sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], //从相册选择 success: (res) => { res.tempFilePaths.forEach((item,index)=>{ that.upload2Qiniu(item); }); } }); } /** * 图片上传七牛云 */ upload2Qiniu(tempFilePaths) { let token = this.data.token; var that = this; wx.uploadFile({ url: 'https://up-z0.qiniup.com', name: 'file', filePath: tempFilePaths, header: { "Content-Type": "multipart/form-data" }, formData: { token: that.data.upToken, }, success: function (res) { let data = JSON.parse(res.data) //data.hash图片的资源名,可直接通过域名加资源名访问 // to do ... }, fail: function (res) { console.log(res) } }); }
如果需要更详细的资料,那么就请自行百度or谷歌吧