搜索

查看: 3112|回复: 11

[JavaScript] vue实现将自己网站(h5链接)分享到微信中形成小卡片的超详细教程

[复制链接]
发表于 2023-5-4 11:49:05 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:49:05 3112 11 看全部
目录
  • 最新更新
  • 前言
  • 准备工作
  • 前端业务实现(超详细)
  • 后端代码实现(超详细)
  • 总结
    最新更新
    2022年12月24日23:58:30
    发现了个问题,解决了好久,问题如下:
    当我直接将链接发送到微信中的时候,然后打开,发现分享出去还是个链接。当我将链接分享到QQ时,发现是自定义卡片形式。我将QQ的卡片在分享到微信里面时,打开分享到微信,是自定义卡片形式。
    这个问题看了好久,淘宝找人花80没有解决,退款给我了,各大技术群问了个遍,也没有解决,CSDN悬赏问答,也未能解决,最后发现是:
    微信不支持直接进去链接分享,不然分享的还是链接,需要从微信的入口进去,比如先将内容生成二维码,然后扫描进去在分享,就可以了!!!

    前言
    我们在分享公众号信息到微信或者群中的时候,会出现一个小卡片,如下所示:

    202302230902482.png

    202302230902482.png


    但是呢,这种小卡片只能走微信的接口来实现,比如我们从公众号、小程序中分享的内容可以是这样的。如果我们将自己的博客分享到微信的话,只会出现个链接。

    202302230902483.png

    202302230902483.png


    那么,试问一下你,分享出来个这样的链接,你会去点吗?会不会以为这就是个钓鱼链接。
    今天,我们就来看看,如何将我们自己的站,搞一个和微信一样的分享卡片出来。

    准备工作
  • 注册一个公众号,该公众号需要能认证的(企业认证)
  • 准备好你的站,前端展示的是vue,别的可以自己对应的转换。
  • 后端用java实现的,别的语言自己转换一下即可。
    请注意,公众号可以是订阅号,也可以是服务号,但是必须是需要企业可以认证的,个人虽然说有的也可以认证,但是没有调用分享接口的权限。

    前端业务实现(超详细)
    weixin-js-sdk帮助文档在这里,可以提现看看,免得后面看到之后,显得那么陌生~
    帮助文档
    下面我们来介绍一下实现步骤:
    打开微信公众平台,在“公众号设置”的“功能设置”里填写“JS接口安全域名”。

    202302230902484.png

    202302230902484.png


    不设置会被拦截,没法使用,大家可以仔细看看是如何设置的,第三点最重要:

    202302230902485.png

    202302230902485.png


    在【基本配置】里面,配置一下你的ip白名单,不设置没法获取access_token,没有toekn,一切都免谈。

    202302230902486.png

    202302230902486.png


    3. 在vue项目中,安装weixin-js-sdk的依赖:
    npm install weixin-js-sdk --save
    在需要分享的vue页面中写代码,先引入安装好的依赖。
    // 引入wxjs
    import wx from "weixin-js-sdk";
    在methods中实现分享的功能:
    getShareInfo() {
          //获取url链接(如果有#需要这么获取)
          var url = encodeURIComponent(window.location.href.split("#")[0]);
                    //获取url链接(如果没有#需要这么获取)
         // var url = encodeURIComponent(window.location.href);
          getSing(url).then(res => {
            wx.config({
              debug: false, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。
              appId: res.data.appId, // 必填,公众号的唯一标识
              timestamp: parseInt(res.data.timestamp), // 必填,生成签名的时间戳
              nonceStr: res.data.nonceStr, // 必填,生成签名的随机串
              signature: res.data.signature, // 必填,签名
              jsApiList: [
                "updateAppMessageShareData",
                "updateTimelineShareData"
              ] // 必填,需要使用的 JS 接口列表
            });
            wx.ready(() => {
              var shareData = {
                title: "每日新闻",
                desc: "2022年12月20日21:47:55每日新闻",
                link: window.location.href,
                imgUrl: "https://blogobs.88688.team/blog/l-logo-y.jpg"
              };
              //自定义“分享给朋友”及“分享到QQ”按钮的分享内容
              wx.updateAppMessageShareData(shareData);
              //自定义“分享到朋友圈”及“分享到 QQ 空间”按钮的分享内容(1.4.0)
              wx.updateTimelineShareData(shareData);
            });
            //错误了会走 这里
            wx.error(function (res) {
              console.log("微信分享错误信息", res);
            });
          });
        },
    代码说明:
  • url 是我们要分享页面的链接,需要传递到后端进行加密签名(后端的代码我们待会儿看)
  • getSing方法是后端进行签名的方法,安全起见,所有config初始化中的关键信息,都从后端往回拿。
  • jsApiList是我们需要实现的功能的方法列表,逗号隔开。
    在created中调用一下getShareInfo方法:
    // 调用分享的事件
        this.getShareInfo();
    前端内容就这些,下面我们看看后端做了哪些操作。

    后端代码实现(超详细)
    获取token:为什么要获取token,微信公众号开发中,不管你做啥操作,都需要这个token,并且有效时间是7200s,也就是两个小时,两小时后就失效,下面是java中获取token的代码:
    /**
         * 获取access_token的值
         * @return
         */
        @GetMapping("/getToken")
        public String getToken() {
            String token = "";
            String path = "token?grant_type=client_credential&appid=" + APPID + "&secret=" + APPSECRET;
            String body = HttpUtil.createGet(WX_GZH_API + path)
                    .execute()
                    .body();
            log.info("获取了token,返回数据" + body);
            JSONObject object = JSON.parseObject(body);
            //获取token
            token = object.getString("access_token");
            //失效时间
            String expires_in = object.getString("expires_in");
            //将token值的值放在redis里面
            redisService.setCacheObject("gzh_access_token", token,7190,TimeUnit.SECONDS);
            return token;
        }
    WX_GZH_API :
    //公众号请求的地址
        public static String WX_GZH_API = "https://api.weixin.qq.com/cgi-bin/";
    APPID 和APPSECRET换成你自己的就行。
    获取api_ticket,这个是用在签名里面的,直接请求接口获取就行。
    /**
         * 获取jsapi_ticket
         * @return
         */
        @GetMapping("/getJsapiTicket")
        public String getJsapiTicket() {
            //获取redis里面的token
            Object access_token = redisService.getCacheObject("gzh_access_token");
            if (access_token==null) {
                access_token = getToken();
            }
            String path = "ticket/getticket?access_token=" + access_token.toString() + "&type=jsapi";
            String body = HttpUtil.createGet(WX_GZH_API + path)
                    .execute()
                    .body();
            log.info("获取了JsapiTicket,返回数据" + body);
            JSONObject object = JSON.parseObject(body);
            //获取ticket
            String ticket = object.getString("ticket");
            //错误码
            Integer errcode = object.getInteger("errcode");
            if(errcode==0){
                //将ticket值的值放在redis里面
                redisService.setCacheObject("gzh_ticket", ticket,7190,TimeUnit.SECONDS);
            }
            return ticket;
        }
    这两个方法我都写了缓存,和是失效时间,并且在用的时候都会去判断缓存里面有没有值,没有的话,我们再去请求重新获取,而不是每次都请求获取,这样会造成接口请求频繁受到限制的问题。
    开始签名:

        /**
         * 开始签名
         */
        @GetMapping("/getSing")
        public ResponseResult getSing(String url){
            //从redis里面获取ticket
            Object ticket = redisService.getCacheObject("gzh_ticket");
            if(ticket==null){
                ticket = getJsapiTicket();
            }
            Map ret = WeChatUtils.sign(ticket.toString(), url);
            JSONObject objectData = new JSONObject();
            for (Map.Entry entry : ret.entrySet()) {
                objectData.put(entry.getKey().toString(),entry.getValue());
            }
            objectData.put("appId", APPID);
            return ResponseResult.success(objectData);
        }
    签名的几个工具类如下所示:
    //******************************************
        // 公众号网页开发
        //******************************************
        public static Map sign(String jsapi_ticket, String url) {
            Map ret = new HashMap();
            String nonce_str = create_nonce_str();
            String timestamp = create_timestamp();
            String string1;
            String signature = "";
            //注意这里参数名必须全部小写,且必须有序
            string1 = "jsapi_ticket=" + jsapi_ticket +
                    "&noncestr=" + nonce_str +
                    "&timestamp=" + timestamp +
                    "&url=" + url;
            System.out.println(string1);
            try
            {
                MessageDigest crypt = MessageDigest.getInstance("SHA-1");
                crypt.reset();
                crypt.update(string1.getBytes("UTF-8"));
                signature = byteToHex(crypt.digest());
            }
            catch (NoSuchAlgorithmException | 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;
        }
        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);
        }

    加密签名接口请求如下:

    202302230902487.jpg

    202302230902487.jpg


    然后我们就实现了,你试试你的可以不。

    总结
    到此这篇关于vue实现将自己网站(h5链接)分享到微信中形成小卡片的文章就介绍到这了,更多相关vue将网站分享到微信小卡片内容请搜索知鸟论坛以前的文章或继续浏览下面的相关文章希望大家以后多多支持知鸟论坛
  • 回复

    使用道具 举报

    发表于 2023-6-28 19:39:36 | 显示全部楼层
    贺老师 2023-6-28 19:39:36 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-29 06:08:02 | 显示全部楼层
    十二音阶囤 2023-6-29 06:08:02 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-6-30 08:39:09 | 显示全部楼层
    惜颜705 2023-6-30 08:39:09 看全部
    楼主,大恩不言谢了!知鸟论坛是最棒的!
    回复

    使用道具 举报

    发表于 2023-6-30 11:07:42 | 显示全部楼层
    123456868 2023-6-30 11:07:42 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-30 21:42:33 | 显示全部楼层
    Gordon520 2023-6-30 21:42:33 看全部
    其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
    回复

    使用道具 举报

    发表于 2023-7-3 09:04:46 | 显示全部楼层
    xinting_6ym 2023-7-3 09:04:46 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-7-3 11:53:00 | 显示全部楼层
    123456833 2023-7-3 11:53:00 看全部
    其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
    回复

    使用道具 举报

    发表于 2023-7-4 00:11:10 | 显示全部楼层
    123456825 2023-7-4 00:11:10 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-4 12:04:31 | 显示全部楼层
    小妖花满楼满fx 2023-7-4 12:04:31 看全部
    楼主,大恩不言谢了!知鸟论坛是最棒的!
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表