移动端微信图片上传

最近做项目,其中有个需求是在微信企业号上实现图片上传操作。一开始我就把重点放在了"移动端图片上传"而不是"微信图片上传",所以各种查资料,找插件,费了好些功夫,实现起来也是各种困难。后来接触到微信公众号,稍微了解了一下,才知道利用微信公众号或者现在已经升级为企业微信的企业号的API,还是挺简单的一个功能。下面我就详细整理一下整个过程,做个笔记,一方面可以帮助到从未接触过这个功能的同学,一方面也方便自己日后翻阅。
1、首先进入微信公众平台,查看JS-SDK开发文档。https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
2、开发文档有详细的步骤说明,但我还是根据我自己做的过程再稍微记录一下。
第一步中的绑定安全域名可不做,不会影响功能的实现。我直接从第二部引进js文件开始的。当我们想要通过微信上传图片时,有两种方法:一种是JS文件调用,一种是接口调用。这里用的是第一种,通过引进JS文件,然后直接调用接口,不再使用URL等接口地址。
3、JS文件的引入:

图1-引进JS文件

4、通过config接口注入权限验证配置:
这一步尤为重要。

移动端微信图片上传_第1张图片
图2-配置信息

1)在开发调试时,可将debug设为true,这样可以看到返回的信息,方便调试bug。但在生产环境上,记得设为false。
2)appId是公众号的唯一标识。项目挂靠在哪个公众号或者企业号,就去找相关负责人拿到appId,这个是固定的值,没有改动,也不需要调用获取。(服务器端,也就是后端开发人员去拿到这个值)
3)除了jsApiList的值需要前端人员根据需要自己写以外,其他参数均需从后端获取。最重要的是其中的签名串,有其特定的生成规则,后端需要根据一定的规则,去调用微信的接口,获取相关参数后生成签名串,然后再将对应的参数传给前端。前端人员获取到这些数据信息后,就可以完成配置信息的注入了。

图3-调用配置接口

4)可能会遇到的问题,当在完成配置信息的注入后,实际开始调用所需接口时,出现报错信息:invalid signature,permission denied,此时解决方法如下:
①首选检查生成签名串的算法(规则)是否正确;
② 其次需要特备注意的是:你在利用参数生成签名的时候,要对所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 string1。这里需要注意的是所有参数名均为小写字符。
③注意参数key值大小写问题;
④生成签名串时,需要前端人员给后端传当前页面的URL,但不包括'#'hash后面的部分。注意前端传值时的格式以及后端接收时的解析方式。
⑤确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。
⑥很重要的一点,确认当前访问页面的URL已经被项目挂靠的公众号或者企业号授权访问。
更多错误信息及详细解决方法,请参考: https://my.oschina.net/u/2308739/blog/371414
5)jsApiList中需要填写的接口。(其实按现在这个操作,是不需要下载图片接口的,因为下载这一操作是由后端实现的。)
图4-jsApiList中的接口

5、配置信息注入并且成功校验完之后,就可以在wx.ready接口下操作相关图片接口了。

移动端微信图片上传_第2张图片
图5-wx.ready接口

6、在wx.ready下调用图片选择、上传、预览等接口时,直接按照操作的顺序调用即可。但其中涉及到的一个问题是,如果前端没有自己的后台,需要和另外一台服务器上的后台进行交互,此时在图片上传时就需要调用后端接口,将图片上传后生成的文件流,最终得到的mediaId传给后端,然后让后端去微信服务器上下载刚刚上传的图片。
7、话不多说,直接上全部代码。

 /** ******************获取微信配置数据********************** */
      var Url = ""; //服务器接口路径
      var oldNet = '';
      var newNet = '';//记录网络状态
      var configData;
      $.ajax({
            url: Url + '/GetSignatureInfo',//后端接口名,可自定义。
//            data: {pageUrl: location.href.split('#')[0]},
            type:"get",
            //params意为参数,是自定义的,用以表明这是传给后台的数据。
            data:{"params":location.href.split('#')[0]},
            contentType:"application/json; charset=utf-8",
            //数据类型为jsonp,解决跨域问题。
            dataType:"jsonp",
            //自定义的jsonp回调函数名,默认为jQuery自动生成的随机函数
            jsonpCallback:"success_jsonpCallback_select",
            //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为callback)
            jsonp:"callbackparam",
            success: function (data) {
//            alert(JSON.stringify(data));
              configData = {
                    debug : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: data.appid, // 必填,公众号的唯一标识
                    timestamp: data.timestamp, // 必填,生成签名的时间戳
                    nonceStr: data.nonceStr, // 必填,生成签名的随机串
                    signature: data.signature,// 必填,签名,见附录1
                    jsApiList : ['chooseImage','previewImage','uploadImage','downloadImage']
                    // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                };
               
               //step2:注入配置信息
               wx.config(configData);
               //step3:通过ready接口处理成功验证
               wx.ready(function () {
                   // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
//                 alert("执行ready方法");
//                 wx.checkJsApi({
//                      jsApiList: ['chooseImage'] // 需要检测的JS接口列表,所有JS接口列表见附录2,
//                      success: function(res) {
//                      // 以键值对的形式返回,可用的api值true,不可用为false
//                      // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
//                      }
//                 });
                   //接口1:获取网络类型
                    wx.getNetworkType({
                        success: function (res) {
                          oldNet = res.networkType; // 返回网络类型2g,3g,4g,wifi
//                        alert("网络类型"+ oldNet);
                        }
                      });
                    // 拍照
//                  alert(document.querySelector('.head_portrait'));
                    document.querySelector('.head_portrait').onclick = function (){
                        
                        $("#tips").html("点击上传图片");
                        
                        var img1 = $('#chooseImage1');
                        //接口2:拍照或从手机相册中选图接口
                        wx.chooseImage({
                            count: 1, // 默认9
                            sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
                            sourceType: ['album', 'camera'],//可以指定来源是相册还是相机,默认二者都有
                            success: function (res) {
                                var imgLocalId = res.localIds;//返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
//                              alert("imgLocalId=" + imgLocalId);
//                              alert(res.contentType);
                                if(!imgLocalId){
                                    alert(2);
                                    fnPicInfo('',imgLocalId,'choose','fb',JSON.stringify(res));
                                }
                                img1.attr('src',imgLocalId);
                                
                                //选择图片之后询问是否确认上传
                                $("#isupload").css("display","block");
                                
                                //不上传或者重新选择
                                $("#isupload_n").click(function(){
                                    $("#isupload").css("display","none");
                                    $("#tips").html("重新选择");
                                    $("#chooseImage1").src("");
                                });
                                
                                //确认上传
                                $("#isupload_y").click(function(){
                                    
                                    $("#isupload").css("display","none");
                                    
                                    //接口3:上传图片接口
                                    wx.uploadImage({
                                        localId: imgLocalId[0], // 需要上传的图片的本地ID,由chooseImage接口获得
                                        isShowProgressTips: 1, // 默认为1,显示进度提示
                                        success: function (res) {
                                            if(res.serverId.indexOf("wxLocalResource://")>=0){
                                                mui.alert('',"图片上传失败,请重新上传!",'');
                                                return;
                                            }
                                            mediaId = res.serverId;
                                            if(!mediaId){
                                              fnPicInfo(mediaId,imgLocalId,'upload','fb',JSON.stringify(res));
                                            } 
                                            img1.attr('src',imgLocalId);
                                            mediaId1 = mediaId;
                                            localId1 = imgLocalId;
                                            //这里再写一个接口,将mediaId以及其他所需参数传到后台。回调函数中不需要写什么信息。
                                            
                                            //准备请求的参数:班级编码、mediaId、上传类型
                                                                                        //注:班级编码和上传类型是根据项目所需上传的参数,大家可根据自己的项目定义,但是mediaId肯定是要上传的。
                                            var requestdata = {     
                                                "classcode": classcode,
                                                "mediaId": mediaId,
                                                "uploadtype": uploadtype
                                            }
                                            alert(JSON.stringify(requestdata));
                                            //调用图片上传接口
                                            post_mediaId(requestdata);
                                        },
                                        fail: function(re){
                                          wx.getNetworkType({
                                          success: function (res) {
                                            $('.hidden_word1').show();
                                            newNet = res.networkType; // 返回网络类型2g,3g,4g,wifi
                                            fnPicInfo('','','upload','fb',re);
                                          }
                                        });
                                        }
                                    });
                                });
                            },
                          fail: function(re){
                            alert(JSON.stringify(re));
                            wx.getNetworkType({
                          success: function (res) {
                            $('.hidden_word1').show();
                            newNet = res.networkType; // 返回网络类型2g,3g,4g,wifi
                            fnPicInfo('','','choose','fb',re);
                          }
                        });
                          }
                        });
                    };
              })
              
             }
        });
          // 向后台数据库传递照片的相关信息,根据实际需求看是否需要传递这些信息。
//        function fnPicInfo(sId,lId,opType,businessType,remark) {
//          remark+="||"+oldNet+"||"+newNet;
//          $.ajax({
//              url:Url+'maintainCommon/addWXMediaRecord',
//              data:{
//                serviceId:sId,
//                localId:lId,
//                clientType:navigator.userAgent,
//                opType:opType,
//                businessType:businessType,
//                remark:remark
//              }
//          });
//        } 
    /********************获取微信配置数据结束********************** */
//向后端传递mediaId的值,以便其能到微信服务器上下载图片到本地服务器。
var post_mediaId = function(requestData){
    var server_IP = "服务器接口地址";  
    $.ajax({
        url: server_IP,
        type:"get",
        //params意为参数,是自定义的,用以表明这是传给后台的数据。
        data:{"params":JSON.stringify(requestData)},
        contentType:"application/json; charset=utf-8",
        //数据类型为jsonp,解决跨域问题。
        dataType:"jsonp",
        //自定义的jsonp回调函数名,默认为jQuery自动生成的随机函数
        jsonpCallback:"success_jsonpCallback_select",
        //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为callback)
        jsonp:"callbackparam",
        //访问成功时的回调函数
        success: function(respose){
            alert(respose.message);
        },
        error: function(data){
            alert("服务器连接失败");
        }
    });
}

你可能感兴趣的:(移动端微信图片上传)