微信开发分享到朋友圈_微信开发微信公众号分享到朋友圈 - CSDN
  • http://www.cnblogs.com/stoneniqiu/p/6286599.htmlhttps://www.cnblogs.com/zhengxu/articles/6743301.html这是微信分享的文章,如果小伙伴正在做这个功能的话,可以参看一下,希望对你有帮助。...

    http://www.cnblogs.com/stoneniqiu/p/6286599.html

    https://www.cnblogs.com/zhengxu/articles/6743301.html

    https://blog.csdn.net/xMric/article/details/80594210

    这是微信分享的文章,如果小伙伴正在做这个功能的话,可以参看一下,希望对你有帮助。

    展开全文
  • 微信公众号开发--微信JS-SDK分享到朋友圈分享给朋友
                         

    之前写过一篇使用微信JS-SDK来实现扫一扫功能的博客

    微信公众号开发–微信JS-SDK扫一扫功能

    在该博客里介绍了微信JS-SDK的基本用法,其中包括以下几个步骤

    这里写图片描述

    还详细介绍了通过config接口注入权限验证配置以及签名算法实现的Java版本

    前两天在做微信分享的时候发现按照以前的思路每次都不能正确获取“分享到朋友圈”按钮点击状态及自定义分享内容接口,而是必须通过一个按钮先点击帮点事件,然后才能获取“分享到朋友圈”按钮点击状态及自定义分享内容接口。

    回顾一下以前扫一扫的js代码

    下面是wx.config的主代码

        <script type="text/javascript">        $(function() {            var timestamp = $("#timestamp").val();//时间戳            var nonceStr = $("#noncestr").val();//随机串            var signature = $("#signature").val();//签名            wx.config({                debug : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。                appId : 'wx622ca8545e5c354b', // 必填,公众号的唯一标识                timestamp : timestamp, // 必填,生成签名的时间戳                nonceStr : nonceStr, // 必填,生成签名的随机串                signature : signature,// 必填,签名,见附录1                jsApiList : [ 'scanQRCode' ]            // 必填,需要使用的JS接口列表,所有JS接口列表见附录2            });        });    </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    下面是扫一扫的代码

    前提是有一个

    <button id="scanQRCode">扫码</button>
    • 1
            $("#scanQRCode").click(function() {            wx.scanQRCode({                needResult : 1,                desc : 'scanQRCode desc',                success : function(res) {                    //扫码后获取结果参数:htpp://xxx.com/c/?6123,截取到url中的防伪码后,赋值给Input                    var url = res.resultStr;                    /* var tempArray = url.split('?');                    var tempNum = tempArray[1]; */                    if(url.indexOf(",")>=0){                        var tempArray = url.split(',');                        var tempNum = tempArray[1];                        $("#id_securityCode_input").val(tempNum);                    }else{                    $("#id_securityCode_input").val(url);                    }                }            });        });
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    以上代码完全没有问题,但是当我配置获取“分享到朋友圈”按钮点击状态及自定义分享内容接口的时候却始终不能成功

    解决方案

    原来是wx.config执行需要时间,而我们把扫一扫放在外面完全没影响。是因为,我们点击扫码的时候wx.config已经加载好了,而我之前的点击一下再分享和扫码是一个道理,为了不让用户点击一下再分享需要将我上面讲的微信JS-SDK使用步骤中的第四步用到

    这里写图片描述

    下面是官方的解释

     

    步骤四:通过ready接口处理成功验证

       

    wx.ready(function(){

       

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

    上面的描述给出了我之前的扫码可以成功而分享不能成功的合理解释。

    像点击扫码这样的事件属于

     

    对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

    而对于分享事件属于

     

    如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行

    下面就来看一下正确的获取“分享到朋友圈”按钮点击状态及自定义分享内容接口的使用方法

        <script type="text/javascript">        $(function() {            var timestamp = $("#timestamp").val();//时间戳            var nonceStr = $("#noncestr").val();//随机串            var signature = $("#signature").val();//签名            wx.config({                debug : true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。                appId : 'wx622ca8545e5c354b', // 必填,公众号的唯一标识                timestamp : timestamp, // 必填,生成签名的时间戳                nonceStr : nonceStr, // 必填,生成签名的随机串                signature : signature,// 必填,签名,见附录1                jsApiList : [ 'scanQRCode','onMenuShareAppMessage' ]            // 必填,需要使用的JS接口列表,所有JS接口列表见附录2            });            wx.ready(function(){                // 分享事件必须放在这里                wx.onMenuShareAppMessage({                      title: '这是一个测试的标题',                      desc: '这个是分享奥朋友圈的描述信息',                      link: 'http://www.baidu.com',                      imgUrl: 'https://www.baidu.com/img/bd_logo1.png',                      trigger: function (res) {                        // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回                        // alert('用户点击发送给朋友');                      },                      success: function (res) {                          alert('分享成功');                      },                      cancel: function (res) {                        alert('你没有分享');                      },                      fail: function (res) {                        alert(JSON.stringify(res));                      }                    });                    //alert('已注册获取“发送给朋友”状态事件');            });        });    </script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    完整的分享到朋友圈和朋友的js代码

    <script type="text/javascript">        $(function() {            var timestamp = $("#timestamp").val();//时间戳            var nonceStr = $("#noncestr").val();//随机串            var signature = $("#signature").val();//签名            wx.config({                debug : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。                appId : 'wx622ca8545e5c354b', // 必填,公众号的唯一标识                timestamp : timestamp, // 必填,生成签名的时间戳                nonceStr : nonceStr, // 必填,生成签名的随机串                signature : signature,// 必填,签名,见附录1                jsApiList : [ 'scanQRCode','onMenuShareAppMessage','onMenuShareTimeline' ]            // 必填,需要使用的JS接口列表,所有JS接口列表见附录2            });            wx.ready(function(){                // wx.hideOptionMenu();                wx.onMenuShareTimeline({                    title: '这是一个测试的标题--程高伟的博客',                    link: 'http://blog.csdn.net/frankcheng5143',                    imgUrl: 'http://avatar.csdn.net/E/B/6/1_frankcheng5143.jpg',                    success: function () {                         // 用户确认分享后执行的回调函数                         alert('分享到朋友圈成功');                    },                    cancel: function () {                         // 用户取消分享后执行的回调函数                         alert('你没有分享到朋友圈');                    }                });                wx.onMenuShareAppMessage({                      title: '这是一个测试的标题--百度',                      desc: '这个是要分享内容的一些描述--百度一下,你就知道',                      link: 'http://www.baidu.com',                      imgUrl: 'https://www.baidu.com/img/bd_logo1.png',                      trigger: function (res) {                        // 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回                      },                      success: function (res) {                          alert('分享给朋友成功');                      },                      cancel: function (res) {                        alert('你没有分享给朋友');                      },                      fail: function (res) {                        alert(JSON.stringify(res));                      }                    });            });        });</script>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    关于绑定域名和签名算法参考

    微信公众号开发–微信JS-SDK扫一扫功能

    效果

    通过菜单进入页面

    这里写图片描述

    进入后呈现的页面

    这里写图片描述

    点击发送给朋友

    这里写图片描述

    出现我们在js中设置的分享内容

    这里写图片描述

    分享成功执行的方法

    这里写图片描述

    分享成功的页面

    这里写图片描述

    用户点击取消,没有分享时的方法

    这里写图片描述

    分享到朋友圈的页面

    这里写图片描述

    分享成功和没有分享和上面的效果一样

    参考文献

     

    微信JS-SDK说明文档

       

    微信公众号开发–微信JS-SDK扫一扫功能

               
    展开全文
  • 微信分享功能

    微信分享功能开发

    用了一天时间,把微信发送给朋友和分享到朋友圈功能开发出来,在这里给大家分享一下,避免大家走弯路。

    一.服务器端程序

    package com.wiimedia.controller;
    
    
    import java.io.IOException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.google.gson.Gson;
    import com.wiimedia.model.Ticket;
    import com.wiimedia.service.ArticleSolrService;
    import com.wiimedia.service.TicketRepository;
    import com.wiimedia.service.TicketRepositorySolr;
    import com.wiimedia.utils.GetRandomStr;
    import com.wiimedia.utils.SignatureBean;
    import com.wiimedia.utils.weixin.WeixinUtil;
    /**
     * 
     * 
     *<p>Project:mryl_phone_v2</p> 
     * 
     *<p>Package:com.wiimedia.controller</p> 
     * 
     *<p>Description:微信分享Controller</p>
     *
     *<p>Company:Wiimedia</p>
     *
     *@Athor:SongJia
     *
     *@Date:2016-7-15 上午09:34:10
     *
     */
    
    @Controller
    @RequestMapping("/WeixinshareController/Api/Inteface")
    public class WeixinshareController {
        @Autowired
        private TicketRepositorySolr ticketRepositorySolr;
    
        @RequestMapping("/getSignature")
        public String getSignature( HttpServletRequest request,
                HttpServletResponse response) throws IOException, ParseException{
            //获取签名页面链接
            String url = request.getParameter("url");
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //从数据库中获取标签,并检查标签是否过期
            Ticket oldticket = ticketRepositorySolr.getTicketById("20160114wiimediamrylsong1152");
            if(oldticket==null){//第一次访问,标签不存在。
                executeTicket(response,"1",url,format);
                return null;
            }else{//标签存在,判断标签是否超时
                String oldAcquiretime = oldticket.getAcquiretime();
                long difference=format.parse(format.format(new Date())).getTime()-format.parse(oldAcquiretime).getTime();
                if(difference>7100000){//标签超时,重新到微信服务器请求标签超时时间为7200秒(7200000毫秒)
                    executeTicket(response,"2",url,format);
                    return null;    
                }else{//标签未超时
                    /** 
                     * 注意事项                                           
                     * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
                     * 2.签名用的url必须是调用JS接口页面的完整URL。                      
                     * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。    
                     * 
                     ****根据第1点要求          signature  配置的时候很容易出错,需要把生成  Ticket的  noncestr和 timestamp传给客户端***
                     */
                    String signature = signature(oldticket.getTicket(),oldticket.getTimestamp(),oldticket.getNoncestr(),url);
                    SignatureBean signatureBean = new SignatureBean();
                    signatureBean.setNoncestr(oldticket.getNoncestr());
                    signatureBean.setSignature(signature);
                    signatureBean.setTimestamp(oldticket.getTimestamp());
                    signatureBean.setUrl(url);
                    response.setContentType("text/html;charset=UTF-8");
                    response.getWriter().print(new Gson().toJson(signatureBean));
                    return null;    
                } 
            }
    
    
        }
        /**
         * 
         *<p>Project:mryl_phone_v2</p> 
         * 
         *<p>:mryl_phone_v2</p> 
         * 
         *<p>Description:更新和获取ticket的方法,因为用的solr所以更新和新增是一样的ID无则添加,有责更新</p>
         *
         *<p>Company:Wiimedia</p>
         *
         *@Athor:SongJia
         *
         *@Date:2016-7-15 上午09:45:00 
         *
         */
        public void executeTicket(HttpServletResponse response,String flag,String url,SimpleDateFormat format) throws IOException{
    
            //获取签名随即字符串
            GetRandomStr randomStr = new GetRandomStr();
            String noncestr = randomStr.getRandomString(15);
            //获取签名时间戳
            String timestamp = Long.toString(System.currentTimeMillis());
            //请求accessToken
            String accessTokenUrl ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=您的APPID&secret=您的密匙";
            String tokenJson = WeixinUtil.httpRequest(accessTokenUrl, "GET", null);
            Gson gson = new Gson();
            ShareAccess_Token token = gson.fromJson(tokenJson, ShareAccess_Token.class);
            String to= token.getAccess_token();
            //获取标签
            String urlTicket ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+to+"&type=jsapi";
            String ticketJson = WeixinUtil.httpRequest(urlTicket, "GET", null);
            Ticket ticket = gson.fromJson(ticketJson, Ticket.class);
            String t = ticket.getTicket();
            //String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
            //我的Ticket ID是写死的
            String acquiretime = format.format(new Date());
            ticket.setTid("20160114wiimediamrylsong1152");
            ticket.setAcquiretime(acquiretime);
            ticket.setTimestamp(timestamp);
            ticket.setNoncestr(noncestr);
            //因为用的SOLR所以更新和添加的方法是一样的,可以根据自己具体需求进行修改,本文不再贴出代码.
            if(flag.equals("2")){
                ticketRepositorySolr.addTicketToSolr(ticket);   
            }else{
                ticketRepositorySolr.addTicketToSolr(ticket);
            }
            /** 
             * 注意事项                                           
             * 1.签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
             * 2.签名用的url必须是调用JS接口页面的完整URL。                      
             * 3.出于安全考虑,开发者必须在服务器端实现签名的逻辑。    
             * 
             *根据第1点要求          signature  配置的时候很容易出错,需要把生成  Ticket的  noncestr和 timestamp传给客户端*
             */
            String signature = signature(t,timestamp,noncestr,url);
            SignatureBean signatureBean = new SignatureBean();
            signatureBean.setNoncestr(noncestr);
            signatureBean.setSignature(signature);
            signatureBean.setTimestamp(timestamp);
            signatureBean.setUrl(url);
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().print(new Gson().toJson(signatureBean));
        }
    
        /**
         * 
         *<p>Project:mryl_phone_v2</p> 
         * 
         *<p>:mryl_phone_v2</p> 
         * 
         *<p>Description:根据标签,时间戳,密匙,URL进行签名</p>
         *
         *<p>Company:Wiimedia</p>
         *
         *@Athor:SongJia
         *
         *@Date:2016-7-15 上午09:37:13 
         *
         */
        private String signature(String jsapi_ticket, String timestamp, String noncestr, String url) {
            jsapi_ticket = "jsapi_ticket=" + jsapi_ticket;
            timestamp = "timestamp=" + timestamp;
            noncestr = "noncestr=" + noncestr;
            url = "url=" + url;
            String[] arr = new String[] { jsapi_ticket, timestamp, noncestr, url };
            // 将token、timestamp、nonce,url参数进行字典序排序
            Arrays.sort(arr);
            StringBuilder content = new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                content.append(arr[i]);
                if (i != arr.length - 1) {
                    content.append("&");
                }
            }
            MessageDigest md = null;
            String tmpStr = null;
    
            try {
                md = MessageDigest.getInstance("SHA-1");
                // 将三个参数字符串拼接成一个字符串进行sha1加密
                byte[] digest = md.digest(content.toString().getBytes());
                tmpStr = byteToStr(digest);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
    
            content = null;
            return tmpStr;
        }
        /**
         * 将字节转换为十六进制字符串
         * 
         * @param mByte
         * @return
         */
        private static String byteToHexStr(byte mByte) {
    
            char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            char[] tempArr = new char[2];
            tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
            tempArr[1] = Digit[mByte & 0X0F];
    
            String s = new String(tempArr);
            return s;
        }
        /**
         * 将字节数组转换为十六进制字符串
         * 
         * @param byteArray
         * @return
         */
        private static String byteToStr(byte[] byteArray) {
            String strDigest = "";
            for (int i = 0; i < byteArray.length; i++) {
                strDigest += byteToHexStr(byteArray[i]);
            }
            return strDigest;
        }
    
    
    
        class ShareAccess_Token{
            private  String access_token;
            private  String expires_in;
            public String getAccess_token() {
                return access_token;
            }
            public void setAccess_token(String accessToken) {
                access_token = accessToken;
            }
            public String getExpires_in() {
                return expires_in;
            }
            public void setExpires_in(String expiresIn) {
                expires_in = expiresIn;
            }
    
        }
    }
    
    

    二.客户端代码.

    <script type="text/javascript">
                var url = window.location.href;
                var articleId = "";
                var shareTitle="明日医疗资讯";
                var shareImgUrl="";
                var userinfo = localStorage.getItem("_userinfo");
                var timestamp;
                var noncestr;
                var signature;
                //获取签名
                 $.ajax({
                         type: "GET",
                         url: "WeixinshareController/Api/Inteface/getSignature",
                         //data:{timestamp:timestamp,noncestr:noncestr,url:url},
                         data:{url:url},
                         success: function(data){
                                    var objData=JSON.parse(data); 
                                    timestamp=objData.timestamp;    
                                    noncestr=objData.noncestr;  
                                    signature=objData.signature;
                                     console.log(objData);
                                     wxShare();
                         }
                     });
                function wxShare(){
                wx.config({
                    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: '您的appid', // 和获取Ticke的必须一样------必填,公众号的唯一标识
                    timestamp:timestamp, // 必填,生成签名的时间戳
                    nonceStr: noncestr, // 必填,生成签名的随机串
                    signature: signature,// 必填,签名,见附录1
                    jsApiList: [
                    'onMenuShareAppMessage'
                    ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                });
                }
                wx.ready(function(){
                     //config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
                     //config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关
                     //接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
    
                    //----------“分享给朋友”
                    wx.onMenuShareAppMessage({
                        title: "明日医疗资讯", // 分享标题
                        desc: shareTitle, // 分享描述
                        link: url, // 分享链接
                        imgUrl: shareImgUrl, // 分享图标
                        type: '', // 分享类型,music、video或link,不填默认为link
                        dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
                        success: function () { 
                            // 用户确认分享后执行的回调函数、
                        },
                        cancel: function () { 
                            // 用户取消分享后执行的回调函数
                        }
                    });
                    //------------"分享到朋友圈"
                    wx.onMenuShareTimeline({
                        title: '明日医疗资讯', // 分享标题
                        link: '', // 分享链接
                        imgUrl: shareImgUrl, // 分享图标
                        success: function () { 
                            // 用户确认分享后执行的回调函数
                        },
                        cancel: function () { 
                            // 用户取消分享后执行的回调函数
                        }
                    });
                    //-------------分享到QQ
                    wx.onMenuShareQQ({
                        title: '明日医疗资讯', // 分享标题
                        desc: shareTitle, // 分享描述
                        link: '', // 分享链接
                        imgUrl: shareImgUrl, // 分享图标
                        success: function () { 
                           // 用户确认分享后执行的回调函数
                        },
                        cancel: function () { 
                           // 用户取消分享后执行的回调函数
                        }
                    });
                    //-------------分享到QQ空间
                    wx.onMenuShareQZone({
                        title: '明日医疗资讯', // 分享标题
                        desc: shareTitle, // 分享描述
                        link: '', // 分享链接
                        imgUrl: shareImgUrl, // 分享图标
                        success: function () { 
                           // 用户确认分享后执行的回调函数
                        },
                        cancel: function () { 
                            // 用户取消分享后执行的回调函数
                        }
                    });
    
                });
    

    三.服务器需要的工具类和Model

    ① Ticket

    package com.wiimedia.model;
    
    
    public class Ticket{
        private String tid;
        private String ticket;   
        private String errcode;
        private String errmsg; 
        private String expires_in;
        private String acquiretime;
        private String noncestr;
        private String timestamp;
    
        public Ticket(String tid, String ticket, String errcode, String errmsg,
                String expiresIn, String acquiretime, String noncestr,
                String timestamp) {
            super();
            this.tid = tid;
            this.ticket = ticket;
            this.errcode = errcode;
            this.errmsg = errmsg;
            expires_in = expiresIn;
            this.acquiretime = acquiretime;
            this.noncestr = noncestr;
            this.timestamp = timestamp;
        }
        public String getTid() {
            return tid;
        }
        public void setTid(String tid) {
            this.tid = tid;
        }
        public String getTicket() {
            return ticket;
        }
        public void setTicket(String ticket) {
            this.ticket = ticket;
        }
        public String getErrcode() {
            return errcode;
        }
        public void setErrcode(String errcode) {
            this.errcode = errcode;
        }
        public String getErrmsg() {
            return errmsg;
        }
        public void setErrmsg(String errmsg) {
            this.errmsg = errmsg;
        }
        public String getExpires_in() {
            return expires_in;
        }
        public void setExpires_in(String expiresIn) {
            expires_in = expiresIn;
        }
        public String getAcquiretime() {
            return acquiretime;
        }
        public void setAcquiretime(String acquiretime) {
            this.acquiretime = acquiretime;
        }
        public String getNoncestr() {
            return noncestr;
        }
        public void setNoncestr(String noncestr) {
            this.noncestr = noncestr;
        }
        public String getTimestamp() {
            return timestamp;
        }
        public void setTimestamp(String timestamp) {
            this.timestamp = timestamp;
        }
    
    
    
    }

    ② 添加到数据库的业务根据自己需要进行实现.
    ③ GetRandomStr

    package com.wiimedia.utils;
    
    import java.util.Random;
    
    public class GetRandomStr {
        /**
         * 
         *<p>Project:mryl_phone_v2</p> 
         * 
         *<p>:mryl_phone_v2</p> 
         * 
         *<p>Description:生成随即字符串 </p>
         *
         *<p>Company:Wiimedia</p>
         *
         *@Athor:SongJia
         *
         *@Date:2016-7-14 上午11:14:46 
         *
         */
        public  String getRandomString(int length) {
            String base = "abcdefghijklmnopqrstuvwxyz0123456789";   
            Random random = new Random();   
            StringBuffer sb = new StringBuffer();   
            for (int i = 0; i < length; i++) {   
                int number = random.nextInt(base.length());   
                sb.append(base.charAt(number));   
            }   
            return sb.toString();   
         }
    }
    

    ④ SignatureBean

    package com.wiimedia.utils;
    
    public class SignatureBean {
        private String noncestr;
        private String url;
        private String timestamp;
        private String signature;
        public String getNoncestr() {
            return noncestr;
        }
        public void setNoncestr(String noncestr) {
            this.noncestr = noncestr;
        }
        public String getUrl() {
            return url;
        }
        public void setUrl(String url) {
            this.url = url;
        }
        public String getTimestamp() {
            return timestamp;
        }
        public void setTimestamp(String timestamp) {
            this.timestamp = timestamp;
        }
        public String getSignature() {
            return signature;
        }
        public void setSignature(String signature) {
            this.signature = signature;
        }
    
    }

    ⑤ WeixinUtil

    package com.wiimedia.utils.weixin;
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.ConnectException;
    import java.net.URL;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    
    /**
         * 
         *<p>Project:mryl_phone_v2</p> 
         * 
         *<p>:mryl_phone_v2</p> 
         * 
         *<p>Description:公众平台接口工具类</p>
         *
         *<p>Company:Wiimedia</p>
         *
         *@Athor:SongJia
         *
         *@Date:2016-7-15 上午09:37:13 
         *
         */
    public class WeixinUtil {
    
        /** 
         * 发起https请求并获取结果 
         *  
         * @param requestUrl 请求地址 
         * @param requestMethod 请求方式(GET、POST) 
         * @param outputStr 提交的数据 
         * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) 
         */  
        public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {  
    
            StringBuffer buffer = new StringBuffer();  
            try {  
                // 创建SSLContext对象,并使用我们指定的信任管理器初始化  
                TrustManager[] tm = { new MyX509TrustManager() };  
                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
                sslContext.init(null, tm, new java.security.SecureRandom());  
                // 从上述SSLContext对象中得到SSLSocketFactory对象  
                SSLSocketFactory ssf = sslContext.getSocketFactory();  
    
                URL url = new URL(requestUrl);  
                HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
                httpUrlConn.setSSLSocketFactory(ssf);  
    
                httpUrlConn.setDoOutput(true);  
                httpUrlConn.setDoInput(true);  
                httpUrlConn.setUseCaches(false);  
                // 设置请求方式(GET/POST)  
                httpUrlConn.setRequestMethod(requestMethod);  
    
                if ("GET".equalsIgnoreCase(requestMethod))  
                    httpUrlConn.connect();  
    
                // 当有数据需要提交时  
                if (null != outputStr) {  
                    OutputStream outputStream = httpUrlConn.getOutputStream();  
                    // 注意编码格式,防止中文乱码  
                    outputStream.write(outputStr.getBytes("UTF-8"));  
                    outputStream.close();  
                }  
    
                // 将返回的输入流转换成字符串  
                InputStream inputStream = httpUrlConn.getInputStream();  
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
    
                String str = null;  
                while ((str = bufferedReader.readLine()) != null) {  
                    buffer.append(str);  
                }  
                bufferedReader.close();  
                inputStreamReader.close();  
                // 释放资源  
                inputStream.close();  
                inputStream = null;  
                httpUrlConn.disconnect();  
                return buffer.toString();  
            } catch (ConnectException ce) {  
                ce.printStackTrace(); 
            } catch (Exception e) {  
                e.printStackTrace();
            }  
            return "";  
        }
    }
    

    四 至此,分享功能已经开发完成,但是,在生成signature的时候会遇到很多问题,这里提供一些wx.config失败的排错方法.

    ① 确认自己的生成的signature是否正确
    在微信提供的http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign进行校验

    ② wx.config中使用的noncestr, timestamp与用以签名中的对应noncestr, timestamp是否一致一致…如上面(一.服务器代码)
    (有可能因为JS页面加载顺序问题,服务器生成的signature,noncestr,timestamp在wx.config中没有获取到)。

    ③ 确认url是页面完整的url,包括GET参数部分
    需要去掉#后面的部分

    ④ config 中的 appid 与用来获取 jsapi_ticket 的 appid 是否一致

    ⑤ 报错{errmsg:config:ok}是debug的正常返回把调试模式关掉就OK
    wx.config debug: false,



    能力有限,希望有问题及时邮箱或留言,谢谢.

    Email:358106209@qq.com

    展开全文
  • 分享到朋友圈分享给朋友接口。 使用jssdk有5个步骤哦,详情请查看微信官方开发文档。 步骤一:绑定域名(先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。) 步骤二:引入JS...

    根据前篇文章使用ThinkPHP3.2获取到的access_token和jsapi_ticket,就可以使用jssdk接口了。如分享到朋友圈和分享给朋友接口。

    使用jssdk有5个步骤哦,详情请查看微信官方开发文档。

    步骤一:绑定域名(先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。)

    步骤二:引入JS文件 

    步骤三:通过config接口注入权限验证配置

    步骤四:通过ready接口处理成功验证

    步骤五:通过error接口处理失败验证

    修改Application/Home/View/Index/index.html

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Document</title>
      <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
    </head>
    <body>
      <b>基础接口accessToken:{$accessToken}</b>
      <p>微信公众号appId:{$signPackage.appId}</p>
      <p>时间戳:{$signPackage.timestamp}</p>
      <p>随机字符串:{$signPackage.nonceStr}</p>
      <p>签名:{$signPackage.signature}</p>
    </body>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
    <script>
      /*
       * 注意:
       * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
       * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
       * 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
       *
       * 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈:
       * 邮箱地址:weixin-open@qq.com
       * 邮件主题:【微信JS-SDK反馈】具体问题
       * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
       */
      wx.config({
          debug: true,
          appId: '{$signPackage.appId}',
          timestamp: {$signPackage.timestamp},
          nonceStr: '{$signPackage.nonceStr}',
          signature: '{$signPackage.signature}',
          jsApiList: [
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
          ]
      });
    
      wx.ready(function () {
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
        // 注册分享朋友圈事件。
        wx.onMenuShareTimeline({
          title: '暮歌尽天下', // 分享标题
          link: 'http://dgnanbo.k10000.top/index.php/Home/Index/index/index', // 分享链接,该链接域名必须与当前企业的可信域名一致
          imgUrl: 'https://avatar.csdn.net/B/8/E/3_cai181191.jpg', // 分享图标
          success: function () {
              alert('success!');
          },
          cancel: function () {
              alert('cancel!');
          }
        });
    
        // 注册分享朋友事件
        wx.onMenuShareAppMessage({
          title: '暮歌尽天下', // 分享标题
          desc: '我们的梦想!在飞!在翱翔!',
          link: 'http://dgnanbo.k10000.top/index.php/Home/Index/index/index', // 分享链接,该链接域名必须与当前企业的可信域名一致
          imgUrl: 'https://avatar.csdn.net/B/8/E/3_cai181191.jpg', // 分享图标
          success: function () {
              alert('success!');
          },
          cancel: function () {
              alert('cancel!');
          }
        });
      });
    
      wx.error(function(res){
          // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
      });
    
    </script>
    </html>
    

    展开全文
  • 截止2017年11月18号,微信小程序官方还尚未开放直接分享到朋友圈的能力,但是劳动人民的智慧是伟大的【狗头】 现在普遍的做法是,生成一张带有小程序码的图片,保存用户相册,用户自行发布图片到朋友圈 我的...

    截止到2017年11月18号,微信小程序官方还尚未开放直接分享到朋友圈的能力,但是劳动人民的智慧是伟大的【狗头】

    现在普遍的做法是,生成一张带有小程序码的图片,保存到用户相册,用户自行发布图片到朋友圈

    我的套路:

    1. 请求后端API生成小程序码(生成小程序码需要access token,后端生成比较方便)
    2. canvas绘制文字和图片到画布
    3. 当用户点击分享到朋友圈时,给用户展示画布,画布转成图片,并将图片保存到相册
    onShow: function () {
          var that = this;
          //1. 请求后端API生成小程序码
          that.getQr();
    
          //2. canvas绘制文字和图片
          const ctx = wx.createCanvasContext('myCanvas');
          var imgPath = '../../../image/intro.png'
          var bgImgPath = '../../../image/bgImgPath.png';
          ctx.drawImage(imgPath, 0, 0, 600, 520);
    
          ctx.setFillStyle('white')
          ctx.fillRect(0, 520, 600, 280);
    
          ctx.drawImage(imgPath,    30, 550, 60, 60);
          ctx.drawImage(bgImgPath,  30, 550, 60, 60);
          ctx.drawImage(imgPath,    410, 610, 160, 160);
    
          ctx.setFontSize(28)
          ctx.setFillStyle('#6F6F6F')
          ctx.fillText('妖妖灵', 110, 590)
    
          ctx.setFontSize(30)
          ctx.setFillStyle('#111111')
          ctx.fillText('宠友们快来围观萌宠靓照', 30, 660)
          ctx.fillText('我在萌爪幼稚园', 30, 700)
    
          ctx.setFontSize(24)
          ctx.fillText('长按扫码查看详情', 30, 770)
          ctx.draw()
      },
      // 3. canvas画布转成图片
          wx.canvasToTempFilePath({
              x: 0,
              y: 0,
              width: 600,
              height: 800,
              destWidth: 600,
              destHeight:800,
              canvasId: 'myCanvas',
              success: function(res) {
                  console.log(res.tempFilePath);
                  that.setData({
                      shareImgSrc : res.tempFilePath
                  })
    
              },
              fail:function (res) {
                  console.log(res)
              }
          })
          //4. 当用户点击分享到朋友圈时,将图片保存到相册
            wx.saveImageToPhotosAlbum({
                filePath:that.data.shareImgSrc,
                success(res) {
                    wx.showModal({
                        title: '存图成功',
                        content: '图片成功保存到相册了,去发圈噻~',
                        showCancel:false,
                        confirmText:'好哒',
                        confirmColor:'#72B9C3',
                        success: function(res) {
                            if (res.confirm) {
                                console.log('用户点击确定');
                            }
                            that.hideShareImg()
                        }
                    })
                }
            })

    canvas绘制单位为px,举个例子,屏幕宽375,绘制375的画布,保存的图片就是375px,图片像素度不够会糊掉,所以我改进了一下套路:

    1. 请求后端API生成小程序码(生成小程序码需要access token,后端生成比较方便)
    2. canvas绘制文字和图片到画布
      绘制2倍屏幕宽度的canvas画布,canvas画布必须是可见状态下,才可以被转成图片,可是他辣么大辣么丑肯定不能给用户看见,那就给他定位定个巨大的数字超出屏幕就好了

    3. 画布转成图片

    4. 当用户点击分享到朋友圈时,给用户展示图片,并将图片保存到相册

      这里写图片描述

    展开全文
  • 一、概述微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫...
  • 微信分享好友+朋友圈准备工作资源申请配置AS新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
  • 讲解什么是微信公众号自定义分享朋友圈、发送朋友;普通的分享链接效果和自定义的分享效果。 自定义分享朋友和发送给朋友可以设置自定义的标题、描述、缩略图。
  • 微信小程序分享朋友圈 近日,微信小程序官方文档更新 wx.showShareMenu(Object object),其中显示小程序可以分享朋友圈啦! 但是,设置分享朋友圈的前提是必须同时设置发生给朋友,也就是说,可以单独设置发送给...
  • 转自:https://www.cnblogs.com/liangzia/p/7569443.htmlh5 微信分享朋友朋友圈生成JS-SDK权限验证签名实现发送给朋友和分享到朋友圈时内容参数自定义 一、微信JS-SDK1. 获得Access Tokenaccess token的获得方法...
  • 小编也经常在微信朋友圈分享一些好的文章或者让人哭或笑的段子,就在手机右上角的三个竖点一键分享就ok了,那么对于分享到朋友圈是怎么实现的呢?对于那种活动分享送流量是怎么定位分享者的呢?而想要将文章发送给...
  • 这里主要是展示了微信分享到朋友圈分享给好友等接口,同时在thinkphp5中封装了动态获取wx.config需要获取的参数。 PHP部分 /** * 微信JSSDK相关 */ class Jssdk extends Controller { private $appid ...
  • 微信小程序直接分享到朋友圈微信小程序直接分享到朋友圈 微信小程序直接分享到朋友圈的实现: 方法很简便:在js中添加onShareTimeline()函数即可,分享到朋友圈的展示形式是小程序logo+小程序名称 目前在朋友圈...
  • 这篇文章主要为大家详细介绍了java开发微信发送给朋友和分享到朋友圈功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 微信分享功能开发 用了一天时间,把微信发送给朋友和分享到朋友圈功能...
  • 微信H5页面分享朋友圈,分享朋友的JS代码。大家一起共勉
  • 微信小程序实现分享到朋友圈 微信小程序分享到朋友圈微信官方没有提供开放接口,所以我们通过canva画布,生成一张图片,图片自带小程序码,用户通过识别二维码,达到分享小程序到朋友圈目的。 效果图: ...
  • https://cloud.tencent.com/developer/article/1039783
  • 微信公众号中经常遇到的问题就是分享链接到微信朋友圈 微信好友一类的需求。 下边走一下需要操作的流程 1.首先再项目中(一般就放自己的公共文件中引入即可,vue中引入index.html中)引入微信js 链接。 目前最高...
  • 1.新建share.js文件import {shareSDK} ...//分享api import wx from 'weixin-js-sdk' export const shareTitle = '测试'; export const shareUrl = '测试连接'; export const shareImg = '测试图片'; export cons...
  • 微信自定义内容 分享到朋友圈成功后朋友看不问题
1 2 3 4 5 ... 20
收藏数 16,949
精华内容 6,779
关键字:

微信开发分享到朋友圈