跟我一起,利用bitcms内容管理系统从0到1学习小程序开发:三、上传图片到服务器
上一篇跟我一起,利用bitcms内容管理系统从0到1学习小程序开发:二、与服务端通信,Hello bitcms!被园子管理员人从首页撤下,理由是“原创精品,排版整齐,有足够的篇幅,与程序员相关,能够让读者从中学到知识”,经过认真深刻的反省,文章确实存在很多问题。
1、排版不够认真。周五下班前匆匆赶稿,只对内容进行简单的加粗换行。就勿勿发表了,确实排版不够精细。
2、原创必须的,但不够精品。内容是有大量的代码段,没有细化分解,阅读起来确实费劲。
3、作为程序员是代码写的多,但文字内容确实写的少,内容生涩是难免的。但我保证,文章里的每段代码都是经过推敲,测试过的。保证不了万全,但一定能调试成功。
问题多多,用心对待吧。再难,也要坚持把《利用bitcms内容管理系统从0到1学习小程序开发》系列文章写完。
一、微信小程序接口
上篇利用wx.request(OBJECT) 服务器进行通信,今天就利用wx.chooseImage(OBJECT)和wx.uploadFile(OBJECT)两个接口配合着进行图片上传。
上传使用图片,必须先选择图片。小程序官方API给的图片选择接口wx.chooseImage(OBJECT),object参数表如下
上传接口wx.uploadFile(OBJECT),object参数表如下
对比下两个接口的参数,选择图片接口wx.chooseImage最多允许选择9张图片,而wx.uploadFile的参数filePath是string类型,最多只能上传一张图片。所以,多图片上传时是应注意,对选择图片参数tempFilePaths循环调用wx.uploadFile上传接口上传图片。
1、添加小程序页面 pages/upload/upload
下面是单张图片上传例子
在upload.wxml页面中添加一个按钮,一个图片容器和进度条,代码如下
<button bindtap='chooseImage'>选择单张图片</button> <view> <image src='{{image}}' mode='aspectFit'></image> <slider max='100' min='0' value='{{percent}}' disabled='disabled'></slider> </view>
界面预览
2、 页面的初始数据
data: { image: '',//图片地址 percent: 0,//上传进度 },
3、图片选择按钮绑定事件chooseImage
/**单张图片 */ chooseImage: function () { var that = this; wx.chooseImage({//使用图片选择接口 count: 1,//图片数量 sizeType: ['compressed'], //original 原图,compressed 压缩图,默认二者都有 success: function (res) { //图片选择后执行的代码 } }); }
参数count:1可选图片个数是1个, sizeType,可以是['compressed'],['original']或['original'],'compressed']
4、上传接口wx.uploadFile集成
/* 向服务器请求或提交数据 parms 为小程序请求对象参数 success为请求成功后的回调数据 fail为请求失败后的回调数据 */ var uploadFile = function (parms, success, fail) { if (!(typeof (parms) == 'object' && parms.url)) {//parms必须为object格式类型数据,且必须提供url属性 if (typeof (fail) == 'function') { fail({ error: 1, message: '通信错误' }); } else { throw Error('参数错误'); } } //提交请求 return wx.uploadFile(utils.extend({ formData: setparms(parms.formData), complete: function (res) { turnResult(res, success, fail); } }, parms)); };
参数 parms为小程序接口wx.uploadFile的Object参数,其它url为必填参数
下面为url参数判断代码,如果没有填写,就调用失败函数或抛出异常。
if (!(typeof (parms) == 'object' && parms.url)) {//parms必须为object格式类型数据,且必须提供url属性 if (typeof (fail) == 'function') { fail({ error: 1, message: '通信错误' }); } else { throw Error('参数错误'); } }
utils.extend(ojbect,object),为JSON对象合并函数。下面为实现代码
//json数据合并 var extend = function (target, source) { for (var p in source) { if (source.hasOwnProperty(p)) { target[p] = source[p]; } } return target; };
setparms(object),功能主要有
A、为服务请求参数的字符型数据进行encodeURIComponent编码,防止参数中有html,js等代码让服务器接收参数抛出异常。
B、为请求参数加个appid,时间戳、随机数和服务器请求数据签名。
/**处理请求参数 */ var setparms = function (data) { data = data ? data : {}; var keys = Object.keys(data); var i = 0; for (i in keys) { if (typeof (data[keys[i]]) == 'string') {//encodeURI 防止提交html,js等代码,服务器出错 data[keys[i]] = encodeURIComponent(data[keys[i]]); } }; //提交数据,添加paddid,时间戳,随机数 utils.extend(data, { appid: appId, timestamp: utils.timestamp(), nonce: utils.random() }); //sign签名 utils.extend(data, { sign: getSign(data) }); return data; };
getSign(object)为签名算法函数,实现过程为各请求参数和秘钥appsecret(小写)按字母顺序排序后进行md5加密。 实现代码如下
/**获取签名 */ var getSign = function (parms) { var sortparms = ''; if (parms && typeof (parms) == 'object') { var keys = Object.keys(parms); keys.push('appsecret');//appsecret不作为参数向服务器提交 keys.sort(); var i = 0; for (i in keys) { var val = parms[keys[i]] == undefined ? '' : parms[keys[i]] + ''; if (keys[i] == 'appsecret') { val = appSecret; } if (val != '') { if (sortparms.length > 0) { sortparms += '&'; } sortparms += keys[i] + '=' + val; } } } //md5加密 return md5(sortparms); };
turnResult(res, success, fail);接口调用成功或失败后执行的代码
//返回数据处理 var turnResult = function (res, success, fail) { var data = {}; if (res.statusCode == 200 && typeof (res.data) == 'object') { data = res.data; } else { if (typeof (res.data) == 'string' && res.data.indexOf('{') == 0) { data = JSON.parse(res.data); } else { data = { error: 1, message: res.data }; } } var data = res.data; if (typeof (data) == 'string') { if (data.indexOf('{') == 0) {//为json数据 data = JSON.parse(data); } else { data = { error: 1, message: data }; } } if (data && data.error == 0) { if (typeof (success) == 'function') { if (data) { success(data); } else { success(); } } else { var msg = res.message || '成功'; wx.showToast({ title: msg, icon: 'success', duration: 2000 }); } } else { data = data || { error: 1, message: '通信错误' }; if (typeof (fail) == 'function') { fail(data); } else { wx.showToast({ image: '/images/icon/error.png', title: data.message || '请求失败', duration: 2000 }); }; } };
上篇文章与服务器通信中的函数都有改动,如果您看了,请按照这篇文章中的函数进行更新。
图片选择按钮绑定事件chooseImage图片选择成功后,完整的代码如下
/**单张图片 */ chooseImage: function () { var that = this; wx.chooseImage({//使用图片选择接口 count: 1,//图片数量 sizeType: ['compressed'], //original 原图,compressed 压缩图,默认二者都有 success: function (res) {//图片选择后执行的代码 that.setData({ image: res.tempFilePaths[0] }); let uploadTask = api.uploadFile({ url: api.url.upload, //仅为示例,非真实的接口地址 filePath: res.tempFilePaths[0], name: 'file', formData: { 'folder': 'test', 'watermark': 1 } }, function (result) { if (result.error == 0) { that.setData({ image: result.data }); }; }, function (result) { that.setData({ image: '' }); }); uploadTask.onProgressUpdate((res) => { that.setData({ percent: res.progress }); }); } }); }
二、服务器接口
1、服务器接口主要实现接收数据和图片保存。接收的参数有folder图片保存文件夹和watermark图片是否加水印
/// <summary> /// 上传 /// </summary> /// <returns></returns> [HttpPost] public JsonResult upload(string folder, int watermark) { var files = this.Request.Files; var path = ""; Entity.AttachmentInfo attachmentInfo = null; if (files.Count > 0) { try { Common.Upload uploadFile = new Common.Upload(); attachmentInfo = uploadFile.save(folder, files.Get(0), watermark == 1); path = attachmentInfo.Path; } catch (Exception ex) { return getResult(bitcms.Entity.Error.错误, ex.ToString()); } } return getResult(bitcms.Entity.Error.请求成功, "上传成功", string.Format("{0}{1}", this.config.SiteDomain, Utils.trimStart(path, "/"))); }
三、源码下载
源码中包含多张图片上传,下载地址 https://pan.baidu.com/s/1qZU4WgO 密码:sojk
四、小记
1、如何跳过域名校验
在微信开发者工具中,可以临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书 选项,跳过服务器域名的校验。此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
就是在开发过程中,可以不使用ssl配置测试地址。微信开发者工具可做如下设置
感谢您的阅读。如果觉得有用的就请各位大神高抬贵手“推荐一下”吧!你的精神支持是博主强大的写作动力。
作者:逐月 《bitcms内容管理系统》开源系统 网站地址:www.bitcms.net
由于博主的水平有限,不足和错误之处在所难免,希望大家能够批评指出。
本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。