微信分享网页之自定义标题、描述、访问连接和图片(亲测通过)

核能气质少年 提交于 2019-12-26 16:27:40

个人亲测通过

用微信打开一个网页,选择右上角的“发送给朋友”后,收到的消息是这样的:

而为了推广效果,我们更希望能自定义标题、描述、访问连接和图片,效果如下图:

下面介绍下怎样来实现这个功能

准备工作
需要一个认证的微信公众号,一定要确定认证
在登录微信公众平台https://mp.weixin.qq.com
在公众号设置–>功能设置,填写设置Js接口安全域名 
Js安全域名是需要把微信提供的文件,放在指定域名或者目录下面可以访问的。

1,引用js

jquery-1.8.3.min.js

https://res.wx.qq.com/open/js/jweixin-1.0.0.js

注意,如果自己的域名模式是https模式,要使用https模式,不然会出现mixed content block,微信js不会执行
JS-sdk中的方法要在获取signature之后再执行,不然有可能会执行错误等,同时分享的调用要在wx.ready方法体里面执行,即微信配置都okay的情况下在执行。

2,页面添加js代码

<script type="application/javascript">
var wxParam = {
            title: "title",// 分享标题(自行修改)
            desc: 'desc', // 分享描述(自行修改)
            link: 'link', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致(自行修改)
            imgUrl: 'link', // 分享图标,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致(自行修改)
            type: "link",//分享类型,music、video或link,不填默认为link,(自行修改)
        }

        var pageUrl = {
            url: (window.location.href).split('#')[0]
        };
        $(function () {
            $.ajax({
                url: "https://www.***.com/***/wxConfig",//获取微信signature的接口(自行修改)
                type: "get",
                data: {
                    link: encodeURIComponent(pageUrl.url)//固定当前页面访问路径,encodeURIComponent是处理后面带参数问题(&符号问题)java代码的使用URLDecoder.decode(link, "UTF-8")接受
                },
                async: false,//同步操作
                cache: false,
                dataType: 'json', <!--jsonp是Ajax专门为了应对跨域而提供的一个解决方案-->
                success: function (data) {
                    wx.config({
                        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                        appId: data.appId, // 必填,公众号的唯一标识(后台获取)
                        timestamp: data.timestamp, // 必填,生成签名的时间戳(后台获取)
                        nonceStr: data.nonceStr, // 必填,生成签名的随机串(后台获取)
                        signature: data.signature,// 必填,签名,见附录1(后台获取)
                        jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone']// 必填,需要使用的JS接口列表,所有JS接口列表见附录2  , 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone'
                        // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
                    });

                    wx.ready(function () {
                        wx.onMenuShareAppMessage({
                            title: wxParam.title,// 分享标题
                            desc: wxParam.desc, // 分享描述
                            link: wxParam.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                            imgUrl: wxParam.imgUrl, // 分享图标
                            type: wxParam.link,//分享类型,music、video或link,不填默认为link,\
                            success: function () {
                                if (wxParam.successFn) {
                                    wxParam.successFn();
                                }
                            }, cancel: function () {
                                if (wxParam.cancelFn) {
                                    wxParam.cancelFn();
                                }
                            }
                        });

                        //分享到朋友圈
                        wx.onMenuShareTimeline({
                            title: wxParam.title,
                            link: wxParam.link,
                            imgUrl: wxParam.imgUrl,
                            success: function () {
                                if (wxParam.successFn) {
                                    wxParam.successFn();
                                }
                            }, cancel: function () {
                                if (wxParam.cancelFn) {
                                    wxParam.cancelFn();
                                }
                            }
                        });
                        //分享到QQ
                        wx.onMenuShareQQ({
                            title: wxParam.title,
                            desc: wxParam.desc,
                            link: wxParam.link,
                            imgUrl: wxParam.imgUrl,
                            success: function () {
                                if (wxParam.successFn) {
                                    wxParam.successFn();
                                }
                            }, cancel: function () {
                                if (wxParam.cancelFn) {
                                    wxParam.cancelFn();
                                }
                            }
                        });
                        //分享到腾讯微博
                        wx.onMenuShareWeibo({
                            title: wxParam.title,
                            desc: wxParam.desc,
                            link: wxParam.link,
                            imgUrl: wxParam.imgUrl,
                            success: function () {
                                if (wxParam.successFn) {
                                    wxParam.successFn();
                                }
                            }, cancel: function () {
                                if (wxParam.cancelFn) {
                                    wxParam.cancelFn();
                                }
                            }
                        });
                        //分享到QQ空间
                        wx.onMenuShareQZone({
                            title: wxParam.title,
                            desc: wxParam.desc,
                            link: wxParam.link,
                            imgUrl: wxParam.imgUrl,
                            success: function () {
                                if (wxParam.successFn) {
                                    wxParam.successFn();
                                }
                            }, cancel: function () {
                                if (wxParam.cancelFn) {
                                    wxParam.cancelFn();
                                }
                            }
                        });


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

                },
                error: function (data) {
                    console.log(data);
                }
            })
        });
</script>

3,java代码

 /**
     * 获取分享数据
     */
    @RequestMapping(value = "/wxConfig", method = RequestMethod.GET)
    @ResponseBody
    public R wxConfig(@RequestParam String link) throws UnsupportedEncodingException {

        String appid = "wxf7******9c9";//公众号的唯一标识(开发者ID(AppID))
        String secret = "cafb0ad5******9c9f286";//开发者密码(AppSecret)
        Map<String, String> ret = new HashMap<String, String>();
        String ticket = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "jsapi_ticket");//从redis获取jsapi_ticket
        String url = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "url");//从redis获取url
        link = URLDecoder.decode(link, "UTF-8");//url地址参数乱问处理
        if (url != null && !link.startsWith("https:")) {
            link = link.replaceAll("http", "https");
        }
        if (StringUtil.isEmpty(ticket) || (StringUtil.isNotEmpty(url) && (!url.equals(link)))) {
            ret = WxJSUtil.sign(appid, secret, link, null);
            for (Map.Entry entry : ret.entrySet()) {
                System.out.println(entry.getKey() + "=" + entry.getValue());
                //把相关参数放入redis
                if ("jsapi_ticket".equals(entry.getKey())) {
                    jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "jsapi_ticket", entry.getValue().toString(), 6000);
                } else if ("timestamp".equals(entry.getKey())) {
                    jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "timestamp", entry.getValue().toString(), 6000);//生成签名的时间戳
                } else if ("nonceStr".equals(entry.getKey())) {
                    jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "nonceStr", entry.getValue().toString(), 6000);//生成签名的随机串
                } else if ("signature".equals(entry.getKey())) {
                    jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "signature", entry.getValue().toString(), 6000);//签名,见附录1
                } else if ("url".equals(entry.getKey())) {
                    jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "url", entry.getValue().toString(), 6000);
                }
            }
        } else {
            String timestamp = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "timestamp");
            String nonceStr = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "nonceStr");
            String signature = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "signature");
            ret.put("url", url);
            ret.put("jsapi_ticket", ticket);
            ret.put("nonceStr", nonceStr);
            ret.put("timestamp", timestamp);
            ret.put("signature", signature);
        }
        return R.ok().put("appid", appid).put("map", ret);


    }

 WxJSUtil.java文件

import net.sf.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;



 /**
     * 微信分享参数处理
     */
    public static Map<String, String> sign(String appid, String secret, String url, String jsapi_ticket) {
        Map<String, String> ret = new HashMap<String, String>();
        if (jsapi_ticket == null) {
            jsapi_ticket = getJSApiTicket(appid, secret);
        }
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String signature = "";
        //注意这里参数名必须全部小写,且必须有序
        String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp + "&url=" + url;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
            System.out.println("JSSDK签名:" + signature);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        return ret;
    }

    /***
     * 获取jsapiTicket
     */
    public static String getJSApiTicket(String appid, String secret) {
        //获取token
        String acess_token = getAccessToken(appid, secret);
        String backData = requestHttp(
                "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
                        + acess_token + "&type=jsapi",
                "get", "");
        String ticket = (String) JSONObject.fromObject(backData).get("ticket");
        System.out.println("调用微信jsapi的凭证票为:" + ticket);
        return ticket;
    }

    /***
     * 获取acess_token
     */
    public static String getAccessToken(String appid, String secret) {
        String result = requestHttp(
                "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                        + appid + "&secret=" + secret,
                "get", "");
        JSONObject jsonObject = JSONObject.fromObject(result);
        System.out.println("access_token" + result);
        String token = jsonObject.getString("access_token");
        return token;
    }




    public static String requestHttp(String path, String method, String params) {
        HttpURLConnection connection = null;
        String result = "";
        try {
            URL url = new URL(path);
            connection = (HttpURLConnection) url.openConnection();
            if (method.equalsIgnoreCase("GET")) {
                connection.connect();
            } else if (method.equalsIgnoreCase("POST")) {
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setUseCaches(false);
                connection.connect();
                OutputStream os = connection.getOutputStream();
                os.write(params.getBytes("UTF-8"));
                os.close();
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    connection.getInputStream(), "UTF-8"));
            String lines;
            StringBuilder sb = new StringBuilder();
            while ((lines = reader.readLine()) != null) {
                sb.append(lines);
            }
            result = sb.toString();
            reader.close();
            connection.disconnect();
            return result;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }

附上获取signature处理代码,在获取signature之前,需要获取accessToken 和 对应的Ticket,这两个方式都比较简单,不在列举

http://demo.open.weixin.qq.com/jssdk/sample.zip

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!