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

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

大家好,我是雄雄。

前言

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

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

那么,试问一下你,分享出来个这样的链接,你会去点吗?会不会以为这就是个钓鱼链接。

今天,我们就来看看,如何将我们自己的站,搞一个和微信一样的分享卡片出来。

准备工作

注册一个公众号,该公众号需要能认证的(企业认证)

准备好你的站,前端展示的是vue,别的可以自己对应的转换。

后端用java实现的,别的语言自己转换一下即可。

请注意,公众号可以是订阅号,也可以是服务号,但是必须是需要企业可以认证的,个人虽然说有的也可以认证,但是没有调用分享接口的权限。

前端业务实现(超详细)

weixin-js-sdk帮助文档在这里,可以提现看看,免得后面看到之后,显得那么陌生~ 帮助文档

下面我们来介绍一下实现步骤:

打开微信公众平台,在“公众号设置”的“功能设置”里填写“JS接口安全域名”。 不设置会被拦截,没法使用,大家可以仔细看看是如何设置的,第三点最重要:

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

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]);

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 +

"×tamp=" + 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);

}

加密签名接口请求如下: 然后我们就实现了,你试试你的可以不。

相关推荐