Vue는 자신의 웹사이트(h5 링크)를 WeChat에 공유하여 작은 카드를 형성하도록 구현합니다(매우 상세함).

안녕하세요 여러분, 저는 Xiongxiong입니다.

여기에 이미지 설명을 삽입하세요.

최신 업데이트

2022년 12월 24일 23시 58분 30초에
문제가 발견되어 해결하는데 오랜 시간이 걸렸습니다.

  1. 링크를 위챗으로 직접 보낸 뒤 열어보니, 공유해도 여전히 링크로 남아 있었습니다.
  2. QQ에 링크를 공유해 보니 커스텀 카드 형태로 되어 있었습니다.
  3. QQ 카드를 위챗에 공유할 때, 위챗에 공유를 오픈하는데, 이는 맞춤형 카드 형태입니다.

이 문제를 오랫동안 보고 있었는데 타오바오에서 누군가에게 80위안을 써서 해결해달라고 했는데 환불받았어요 주요 기술그룹에 다 물어봤는데 해결이 안됐어요 CSDN 바운티 Q&A도 실패했어요 마침내 알아냈습니다: WeChat은 직접적인 통신을 지원하지 않습니다
. 공유하려면 링크를 입력하세요. 그렇지 않으면 링크가 계속 공유됩니다. WeChat 입구에서 들어가야 합니다. 예를 들어 먼저 QR 코드를 생성하세요. 콘텐츠를 스캔한 후 공유하면 끝입니다! ! !

머리말

공식 계정 정보를 WeChat이나 그룹에 공유하면 아래와 같이 작은 카드가 나타납니다.
여기에 이미지 설명을 삽입하세요.

하지만 이런 종류의 작은 카드는 위챗 인터페이스를 통해서만 구현할 수 있으며, 예를 들어 공식 계정이나 미니 프로그램에서 공유하는 콘텐츠는 다음과 같습니다. 블로그를 WeChat에 공유하면 링크만 나타납니다.

여기에 이미지 설명을 삽입하세요.
그럼 제가 이런 링크를 공유하면 클릭하시겠습니까? 이것이 피싱 링크라고 생각하시나요?

오늘은 위챗과 동일한 우리 홈페이지 공유카드를 만드는 방법을 살펴보겠습니다.

준비

  • 인증이 필요한 공용계좌 ​​등록(기업인증)
  • 사이트를 준비하고 프런트 엔드에 표시되는 내용 vue과 그에 따라 다른 내용을 변환할 수 있습니다.
  • 백엔드는 java다른 언어로 구현되며 직접 변환할 수 있습니다.

공용 계정은 구독 계정일 수도 있고 서비스 계정일 수도 있으나 기업의 인증을 받아야 하며, 일부 개인은 인증은 가능하지만 공유 인터페이스를 호출할 수 있는 권한이 없다는 점을 참고하시기 바랍니다.

프론트 엔드 비즈니스 구현(매우 상세함)

weixin-js-sdk도움말 문서는 여기 있으니, 나중에 보시고 나면 별로 낯설지 않도록 빼서 읽어보시면 됩니다~
도움말 문서

아래에 구현 단계를 소개하겠습니다.

  1. WeChat 공개 플랫폼을 열고 "공식 계정 설정"의 "기능 설정"에서 "JS 인터페이스 보안 도메인 이름"을 입력하세요.
    여기에 이미지 설명을 삽입하세요.
    설정하지 않으면 차단되어 사용할 수 없습니다. 설정 방법을 자세히 살펴보세요. 세 번째 사항이 가장 중요합니다.
    여기에 이미지 설명을 삽입하세요.
  2. [기본 설정]에서 ip화이트리스트를 구성합니다. 설정하지 않으면 얻을 수 없습니다 access_token. 설정하지 않으면 toekn이야기할 필요가 없습니다.

여기에 이미지 설명을 삽입하세요.
3. vue프로젝트 에서 weixin-js-sdk다음 종속성을 설치합니다.

npm install weixin-js-sdk --save
  1. 공유해야 하는 페이지에 코드를 작성 vue하고 먼저 설치된 종속성을 소개합니다.
// 引入wxjs
import wx from "weixin-js-sdk"; 
  1. 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우리가 구현해야 하는 함수의 메서드 목록을 쉼표로 구분하여 나열한 것입니다.
  1. 다음에서 메소드를 created호출하십시오 getShareInfo.
// 调用分享的事件
    this.getShareInfo();

이것이 프론트엔드 콘텐츠의 전부입니다. 백엔드가 어떤 작업을 하는지 살펴보겠습니다.


백엔드 코드 구현(매우 상세함)

  1. 획득 token: 왜 획득해야 합니까 token?WeChat 공개 계정을 개발하는 동안 어떤 작업을 하든 이것이 필요하며 token유효 시간은 7200초로 2시간입니다. 2시간 후에 만료됩니다. 다음은 tokenJava에서 얻은 코드 입니다 .
 /**
     * 获取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자신의 것으로 교체하십시오.

  1. Obtain 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;
    }

이 두 가지 방법에 대해 캐시를 작성해 놓았는데, 만료시간이 되어서 이를 사용할 때 캐시에 값이 있는지 판단하게 되고, 없으면 매번 요청하는 것이 아니라 다시 얻어오도록 요청하게 되는데, 이로 인해 인터페이스 요청이 자주 제한되는 문제가 발생합니다.

  1. 서명 시작:

    /**
     * 开始签名
     */
    @GetMapping("/getSing")
    public ResponseResult getSing(String url){
    
    
        //从redis里面获取ticket
        Object ticket = redisService.getCacheObject("gzh_ticket");
        if(ticket==null){
    
    
            ticket = getJsapiTicket();
        }
        Map<String, String> 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<String, String> sign(String jsapi_ticket, String url) {
    
    
        Map<String, String> ret = new HashMap<String, String>();
        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);
    }

암호화된 서명 인터페이스 요청은 다음과 같습니다.
여기에 이미지 설명을 삽입하세요.
그런 다음 이를 구현했으니 직접 시도해 볼 수 있습니다.

Supongo que te gusta

Origin blog.csdn.net/qq_34137397/article/details/128399496
Recomendado
Clasificación