• 【微信公众号开发】【10】JSJDK相关


    前言:

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

    缺点:使用上有限制(如:上传文件有大小限制),很容易踩坑,部分安卓手机及电脑端不支持pjax

    总结:上手容易,坑很多 

    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 = "https://i.cnblogs.com/"; //当前域名
    
    //单张
    $("#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
            });
        }
    });
  • 相关阅读:
    avalon做的抽奖效果
    [转]谈谈前端渲染 VS 后端渲染
    迷你MVVM框架 avalonjs 1.3.7发布
    迷你MVVM框架 avalonjs 学习教程22、avalon性能大揭密
    Facebook React 和 Web Components(Polymer)对比优势和劣势
    迷你MVVM框架 avalonjs 学习教程21、双向绑定链
    迷你MVVM框架 avalonjs 学习教程20、路由系统
    html中的数据岛:利用DSO和javascript在html中动态加载和浏览xml数据
    使用JS的 FileReader 读取本地文本文件(可兼容各种浏览器)
    简易版jquery
  • 原文地址:https://www.cnblogs.com/huashengweilong/p/7755970.html
Copyright © 2020-2023  润新知