zoukankan      html  css  js  c++  java
  • 跟我一起,利用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

    由于博主的水平有限,不足和错误之处在所难免,希望大家能够批评指出。

    本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Java 并发性和多线程
    Java多线程整理
    线程死锁问题
    随机生成长度为len的密码,且包括大写、小写英文字母和数字
    ConcurrentHashMap原理分析
    并发 并行 同步 异步 多线程的区别
    Android与javaScript的交互
    Android6.0 新特性详解
    Android 6.0 新功能及主要 API 变更
    安装 Python-Client
  • 原文地址:https://www.cnblogs.com/zhuyue/p/8317145.html
Copyright © 2011-2022 走看看