前言:

1,优点:官方提供的,会调用后还算使用方便,不用费劲了解各个原生组件


总结:上手容易,坑很多 

2,官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 (内容较多)

3,退出页面

4,选择性隐藏右上角的功能按钮

5,自定义分享内容

6,上传图片

7,图片查看

正文:

步骤:绑定域名——引入JS文件——权限验证——通过ready接口处理成功验证/通过error接口处理失败验证   ( 前三步请参照第二章—JS接口安全域名部分 )

1,权限验证


//1.js 入口页面URL,只在主页引用。
//主要为了解决使用pjax的页面,在获取微信授权时,在微信PC端,手机端表现形式不一致的问题
var entryUrl = location.href.split("#")[0]; 

//2.js 每个页面引用
var wxCount = 0; //获取授权失败后,重新尝试
var WX_URL = "http://" + document.domain; //当前域名

$(function () {    
    //获取授权
    var wxUrl = location.href.split("#")[0];
    getWxTicket(wxUrl); 
    //微信的签名只认第一个加载的页面的URL,只在入口签名一次在iOS上是可以的,但在安卓有些机型会签名不上,所以保险起见,每个页面都签名一次
}); 

function getWxTicket(wxUrl){
    var url = window.location.href;
    if(url.indexOf("/index") != -1){ //回退后首页签名不上,此处为特殊处理,应当不需要用到
        wxUrl = WX_URL + "/index";
    }
    
    $.ajax({
        type : "post",
        url : "/getTicket",
        data : {
            "url" : wxUrl
        },
        dataType : "json",
        success : function(data){
            var obj = data;
            wx.config({
                debug: false, //开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: obj.appId, //必填,公众号的唯一标识
                timestamp: obj.timestamp, //必填,生成签名的时间戳
                nonceStr: obj.nonceStr, //必填,生成签名的随机串
                signature: obj.signature,//必填,签名,见微信开发文档附录1
                jsApiList: ["hideMenuItems","showMenuItems","chooseImage","previewImage","uploadImage","downloadImage","closeWindow",
                            "onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareWeibo","onMenuShareQZone",
                            "scanQRCode", "getLocation"], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
            });
             wx.error(function (res) {
                if(wxCount == 0){
                    wxCount = 1;
                    getWxTicket(entryUrl);
                }    
            });
        }
    });
}



2,ready接口/error接口



wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。
    对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});



wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});



3,退出页面


WeixinJSBridge.invoke('closeWindow',{},function(res){});



但由于这个事件有响应时间,所以在还没退出时点回退按钮会退到上一页面

改进的写法:



history.pushState(null, null, document.URL);
setTimeout(function(){WeixinJSBridge.invoke('closeWindow',{},function(res){});},1000);



注:不知是否是我采用pjax的原因,部分手机出现进入页面立即闪退而不是点击回退再退出的问题,所以我实际开发中是把没有用这个方法的,直接都是退到入口页面

4,选择性隐藏右上角的功能按钮



wx.ready(function (){
    wx.hideMenuItems({
        menuList: [
        'menuItem:favorite',
        'menuItem:share:qq',
        'menuItem:share:QZone',
        'menuItem:share:weiboApp',
        'menuItem:share:facebook',
        'menuItem:openWithQQBrowser',
        'menuItem:openWithSafari',
        'menuItem:share:email',
        'menuItem:originPage',
        'menuItem:copyUrl',
        'menuItem:share:brand'
        ]
    });
    wx.showMenuItems({
        menuList: [        
        'menuItem:addContact'
        ]
    });
});



5,自定义分享内容



wx.ready(function (){        
        //分享给好友
        wx.onMenuShareAppMessage({
            title: title,//标题
            desc: desc,//描述
            link: shareUrl,//地址
            imgUrl: 'http://XX.png',//分享图片,如果不设定,会读取该页面第一张
            type: '', // 分享类型,music、video或link,不填默认为link
            dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
            success: function () { 
            },
            cancel: function () { 
            }
        });
        //分享到朋友圈
        wx.onMenuShareTimeline({
            title: title,
            desc:desc,
            link: shareUrl,
            imgUrl: 'http://XX.jpg',
            success: function () { 
            },
            cancel: function () { 
            }
        });
        wx.onMenuShareQQ({
            title: title,
            desc: desc,
            link: shareUrl,
            imgUrl: '',
            success: function () { 
               // 用户确认分享后执行的回调函数
            },
            cancel: function () { 
               // 用户取消分享后执行的回调函数
            }
        });
        wx.onMenuShareWeibo({
            title: title,
            desc: desc,
            link: shareUrl,
            imgUrl: '',
            success: function () { 
               // 用户确认分享后执行的回调函数
            },
            cancel: function () { 
                // 用户取消分享后执行的回调函数
            }
        });
        wx.onMenuShareQZone({
            title: title,
            desc: desc,
            link: shareUrl,
            imgUrl: '',
            success: function () { 
               // 用户确认分享后执行的回调函数
            },
            cancel: function () { 
                // 用户取消分享后执行的回调函数
            }
        });
    });



6,上传图片(如果只是上传到微信,微信只会保留一段时间的,所以上传后还要下载回本地)



function chooseImage() {
    var length = $("#img1 li").length;//已经上传的张数
    var count = 3-length;
    if(length < 3){
         wx.chooseImage({
            count: count, // 默认9
            sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
            sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
            success: function (res) {
                var localIds = res.localIds;
                if(localIds.length == 0){
                    layer.open({content:"请先选择图片", btn: '我知道了'});
                    return;
                }
                uploadImage(0,localIds.length,localIds,"exercise");
            }
        });
    }else{
        layer.open({content:"只能上传3张图片哦", btn: '我知道了'});
    }
};



/** 
 * 该方法用来上传文件 
 * @param start:本地ID开始的下标(当前上传的图片的下标) 
 * @param end:本地ID的总个数(也就是选择的图片的总个数) 
 * @param IDs:当前批次选择的所有图片在本地ID的集合 
 * @param source:来源,后台根据这个存入不同的文件夹 
 * */  
function uploadImage(start,end,IDs,source){  
    if(start<end){  
        var localId = IDs[start].toString();  
        wx.uploadImage({  
            localId: localId,  
            isShowProgressTips: 1,//显示进度条  
            success: function (res) {  
                var serverId = res.serverId; // 返回图片的服务器端ID  
                serverId = serverId.toString();  
                //上传到服务器
                $.ajax({
                    type : "POST",
                    url : "downloadMedia",
                    data:{
                        "mediaId" : serverId,
                        "source" : source,
                    },
                    success : function(data){
                        if(data == ""){
                            layer.open({content:"格式错误", btn: '我知道了'}); 
                            return;
                        }else if(data == "false"){
                            layer.open({content:"access_token失效,请联系开发人员", btn: '我知道了'}); 
                            return;
                        }else{
                            if(source == "issue"){
                                $("#img1").html("<li data-path="+data+"><img src="+data+" style='cursor:pointer' class='myImg'></li>");
                            }else{   
                                $("#img1").append("<li data-path="+data+"><img src="+data+" style='cursor:pointer' class='myImg'></li>");
                            }
                        }                        
                    },
                    error : function(){
                        layer.open({content:"抱歉,图片上传失败,请稍后再试", btn: '我知道了'});      
                    }
                });                   
                start++;  
                //延迟1s,这1s用来显示图片信息,避免出现连续上传几次最后一次性显示图片的问题  
                setTimeout(function(){  
                    uploadImage(start,end,IDs,source);  
                },500);  
            }  
        });  
    }  
};



@ApiOperation(value = "使用微信上传图片接口后将图片下载回本地", notes = " ", response = Result.class)
@RequestMapping(value = "downloadMedia", method = RequestMethod.POST)
public String downloadMedia(String mediaId, String appId, String active) throws IOException { 
    logger.info(String.format("downloadMedia mediaId:%s appId:%s active:%s", mediaId, appId, active));
    
    String savePath = dealSavePath(active); //拼接存储路径,视情况而定
    
    String access_token = WeixinUtil.getAccessToken(appId);                          
    String requestUrl = String.format(WxConfig.MEDIA_GET_URL, access_token, mediaId); // 拼接请求地址 
    
    try {   
        URL url = new URL(requestUrl);   
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();   
        conn.setDoInput(true);   
        conn.setRequestMethod("GET");
        String fileExt = getFileType(conn.getHeaderField("Content-Type"));  // 根据内容类型获取扩展名     
        
        if (fileExt.equals("") || !fileExt.equals(".jpg")){
            return "";
        }
        
        String fileName = mediaId + fileExt;
        String filePath = Config.MEDIA_FILE + savePath + fileName; 
        
        BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());   
        FileOutputStream fos = new FileOutputStream(new File(filePath));   
        byte[] buf = new byte[8096];   
        int size = 0;   
        while ((size = bis.read(buf)) != -1)    
            fos.write(buf, 0, size);   
        fos.close();   
        bis.close();     
        conn.disconnect(); 
        
        String realUrl = Config.REAL_MEDIA_DOMAIN + savePath + fileName;
        logger.info("downloadMedia success, realUrl=" + realUrl);
        
        return realUrl;
    } catch (Exception e) {   
        logger.error("downloadMedia error:" + e.getMessage());
        return "";  
    }        
}



7,图片查看(这里的图片地址必须要加上域名)



var imgDomain = ""; //当前域名

//单张
$("#pjax-content").on("click", ".my_singleImg",function(event) {
    var imgArray = [];
    var oParent = $(this).parent();
    var imgSrc = $(this).data("src"); //当前图片路径
    var curImageSrc = imgSrc.indexOf("http") != -1 ? imgSrc : imgDomain + imgSrc;
    
    if (curImageSrc && !oParent.attr("href")) {       
        var itemSrc = $(this).data("src");
        var curItemSrc = itemSrc.indexOf("http") != -1 ? itemSrc : imgDomain + itemSrc;
        imgArray.push(curItemSrc);
        wx.previewImage({
            current: curImageSrc,
            urls: imgArray
        });
    }
});

//多张
$("#pjax-content").on("click", ".my_moreImg",function(event) {
    var imgArray = [];
    var oParent = $(this).parent();
    var imgSrc = $(this).data("src");
    var curImageSrc = imgSrc.indexOf("http") != -1 ? imgSrc : imgDomain + imgSrc;
    
    if (curImageSrc && !oParent.attr("href")) {
        $(this).parent().find(".my_moreImg").each(function(index, el) {
            var itemSrc = $(this).data("src");
            var curItemSrc = itemSrc.indexOf("http") != -1 ? itemSrc : imgDomain + itemSrc;
            imgArray.push(curItemSrc); 
        });
        wx.previewImage({
            current: curImageSrc,
            urls: imgArray
        });
    }
});