日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

微信自定义分享链接内容,wx.updateAppMessageShareData、wx.updateTimelineShareData、wx.onMenuShareTimeline

發布時間:2023/12/16 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信自定义分享链接内容,wx.updateAppMessageShareData、wx.updateTimelineShareData、wx.onMenuShareTimeline 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微信分享自定義鏈接

  • 目錄
    • 問題與需求
    • 準備
    • 公眾號設置
    • 代碼
      • 后端代碼(完整代碼在附錄)
        • application.properties文件配置
        • (1)獲取accessToken
        • (2)獲取jsapiTicket
        • (3)生成簽名
        • 生成wx.config
        • 接口返回wx.config
      • 前端代碼(完整代碼在附錄)
    • 測試
    • 附錄
      • 后端完整代碼
        • 微信工具類.java
        • 網絡工具類.java
        • controler交互
        • js
      • 常見問題
        • 獲取JSSDK權限成功但分享無效果
        • 本地調試無效果
        • 微信頁面緩存

目錄

問題與需求

問題:

需求:

準備

認證的公眾號或者服務號(記住開發者ID、開發者密碼)

備案過的域名

公眾號設置

設置-開發-基本配置-IP白名單-添加網站服務器IP地址
設置-公眾號設置-功能設置-設置業務域名與JS接口安全域名(即網站的域名)(這里需要加入認證TXT文件到項目)

代碼

后端代碼(完整代碼在附錄)

根據官方文檔,可以得知大步驟為->綁定域名->引入JS文件->通過config接口注入權限驗證配置。

也就是說后端只要返回wx.config所需參數即可。

wx.config({debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。appId: '', // 必填,公眾號的唯一標識timestamp: , // 必填,生成簽名的時間戳nonceStr: '', // 必填,生成簽名的隨機串signature: '',// 必填,簽名jsApiList: [] // 必填,需要使用的JS接口列表 });

除了簽名,其他參數都可直接獲取或生成,查閱官方簽名文檔,可知需要先生成jsapi_ticket,然后再根據文檔需求生成簽名。

根據文檔可知生成簽名步驟:獲取accessToken -> 生成jsapi_ticket ->簽名算法 -> sha1 加密

application.properties文件配置

#微信配置 WX_APPID=xxxx #appId WX_APPSECRET=xxxxx #密鑰 WX_GRANTTYPE=client_credential

(1)獲取accessToken

@Scheduled(initialDelay = 1000, fixedDelay = 100*60*1000)public String getAccessToken() {Map<String,String> resultMap=new HashMap<>();//獲取access_tokenString url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";//設置參數Map<String, Object> map = new HashMap<>();map.put("appid", WX_APPID);map.put("secret", WX_APPSECRET);//發送get請求String accessTokenResult = ((Map<String, String>) JSON.parse(httpUtil.GETclient(url, map))).get("access_token");tokenAll = accessTokenResult;return accessTokenResult;}

(2)獲取jsapiTicket

@Scheduled(initialDelay = 1000, fixedDelay = 100*60*1000)public String getJsapiTicket() {Map<String,Object> map=new HashMap<>();String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={ACCESS_TOKEN}&type=jsapi";//設置參數map.put("ACCESS_TOKEN", getAccessToken());//發送get請求String ticket = ((Map<String, String>) JSON.parse(httpUtil.GETclient(url, map))).get("ticket");ticketAll = ticket;return ticket;}

(3)生成簽名

這個方法是參考官方的簽名算法文檔

/*** 簽名* @return*/public 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 stringAppend;String signature = "";//注意這里參數名必須全部小寫,且必須有序stringAppend = "jsapi_ticket=" + jsapi_ticket +"&noncestr=" + nonce_str +"&timestamp=" + timestamp +"&url=" + url;System.out.println(stringAppend);try{MessageDigest crypt = MessageDigest.getInstance("SHA-1");crypt.reset();crypt.update(stringAppend.getBytes("UTF-8"));signature = byteToHex(crypt.digest());}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);ret.put("appId", WX_APPID);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;} /*** 隨機字符串*/public String create_nonce_str() {return UUID.randomUUID().toString();}/*** 時間戳* @return*/private static String create_timestamp() {return Long.toString(System.currentTimeMillis() / 1000);}

生成wx.config

public Map<String,String> wxConfig(String url) {String jsapi_ticket = ticketAll;// 注意 URL 一定要動態獲取,不能 hardcodeMap<String, String> ret = sign(jsapi_ticket, url);for (Map.Entry entry : ret.entrySet()) {System.out.println(entry.getKey() + ", " + entry.getValue());}return ret;}

接口返回wx.config

/*** 獲取wechatConfig信息* @param url 訪問頁面的地址* @return*/@GetMapping("/getWechatConfig")public Map<String,String> getWechatConfig(String url){return wechatUtil.wxConfig(url);}

前端代碼(完整代碼在附錄)

分享接口文檔
引入JS文件

<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js" type="text/javascript"></script>

JS代碼

//將url 存進緩存下 var url = "https://" + window.location.host; //服務器的url var urlCureent = encodeURIComponent(location.href); //當前頁面的url $.ajax({async:true,dataType:"json",type:"GET",url: url + "/verification/getWechatConfig?url=" + urlCureent,contentType: "application/json; charset=utf-8",success:function(data){wx.config({debug: 0,appId: data.appId,timestamp: data.timestamp,nonceStr: data.nonceStr,signature: data.signature,jsApiList: ["updateAppMessageShareData", "updateTimelineShareData","onMenuShareTimeline","onMenuShareAppMessage"]});wx.ready(function () { //需在用戶可能點擊分享按鈕前就先調用wx.updateAppMessageShareData({title: cardVo.cardName + "個人名片", // 分享標題desc: cardVo.cardNameEn + "'s card", // 分享描述link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標success: function () {console.log("success");// 設置成功}});wx.updateTimelineShareData({title: cardVo.cardName + "個人名片", // 分享標題link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標success: function () {console.log("success2");// 設置成功}});wx.onMenuShareTimeline({title: cardVo.cardName + "個人名片", // 分享標題desc: cardVo.cardNameEn + "'s card", // 分享描述link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標});wx.onMenuShareAppMessage({title: cardVo.cardName + "個人名片", // 分享標題link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標});});}});

測試


可以看到已經成功獲取JSSDK 權限

附錄

后端完整代碼

微信工具類.java

import com.alibaba.fastjson.JSON; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component;import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.Formatter;/*** @program:gzdm* @author:wihenne* @creatTime:2021/05/05**/ @Component @PropertySource({"classpath:application.properties"}) public class WechatUtil {@Value("${WX_APPID}")String WX_APPID;@Value("${WX_APPSECRET}")String WX_APPSECRET;@Value("${WX_GRANTTYPE}")String WX_GRANTTYPE;@AutowiredHttpUtil httpUtil;public static String tokenAll; //微信公眾號的accessToken對象,由于請求次數有限制,這里使用全局靜態變量保存起來public static String ticketAll;//使用全局靜態變量存儲ApiTicket對象,當然如果使用緩存框架保存當然更好,這邊只是做一個簡單示例//用于下面返回隨機字符串的函數private final static String string = "0123456789";final private static char[] chars = string.toCharArray();/*** 獲取公眾號的ACCESS_TOKEN** @return string*///刷新access_token 100分鐘刷新一次,服務器啟動的時候刷新一次(access_token有效期是120分鐘,我設置的是每100分鐘刷新一次)@Scheduled(initialDelay = 1000, fixedDelay = 100*60*1000)public String getAccessToken() {Map<String,String> resultMap=new HashMap<>();//獲取access_tokenString url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appid}&secret={secret}";//設置參數Map<String, Object> map = new HashMap<>();map.put("appid", WX_APPID);map.put("secret", WX_APPSECRET);//發送get請求String accessTokenResult = ((Map<String, String>) JSON.parse(httpUtil.GETclient(url, map))).get("access_token");tokenAll = accessTokenResult;return accessTokenResult;}/*** 獲取jsapiTicket** @return map*/@Scheduled(initialDelay = 1000, fixedDelay = 100*60*1000)public String getJsapiTicket() {Map<String,Object> map=new HashMap<>();String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={ACCESS_TOKEN}&type=jsapi";//設置參數map.put("ACCESS_TOKEN", getAccessToken());//發送get請求String ticket = ((Map<String, String>) JSON.parse(httpUtil.GETclient(url, map))).get("ticket");ticketAll = ticket;return ticket;}/*** 生成wx.config** @return map*/public Map<String,String> wxConfig(String url) {String jsapi_ticket = ticketAll;// 注意 URL 一定要動態獲取,不能 hardcodeMap<String, String> ret = sign(jsapi_ticket, url);for (Map.Entry entry : ret.entrySet()) {System.out.println(entry.getKey() + ", " + entry.getValue());}return ret;}/*** 簽名* @return*/public 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 stringAppend;String signature = "";//注意這里參數名必須全部小寫,且必須有序stringAppend = "jsapi_ticket=" + jsapi_ticket +"&noncestr=" + nonce_str +"&timestamp=" + timestamp +"&url=" + url;System.out.println(stringAppend);try{MessageDigest crypt = MessageDigest.getInstance("SHA-1");crypt.reset();crypt.update(stringAppend.getBytes("UTF-8"));signature = byteToHex(crypt.digest());}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);ret.put("appId", WX_APPID);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;}//Sha1加密public static String getSha1(String str){if(str==null||str.length()==0){return null;}char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};try {MessageDigest mdTemp = MessageDigest.getInstance("SHA1");mdTemp.update(str.getBytes("UTF-8"));byte[] md = mdTemp.digest();int j = md.length;char buf[] = new char[j*2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];buf[k++] = hexDigits[byte0 >>> 4 & 0xf];buf[k++] = hexDigits[byte0 & 0xf];}return new String(buf);} catch (Exception e) {return null;}}/*** 隨機字符串*/public String create_nonce_str() {return UUID.randomUUID().toString();}/*** 時間戳* @return*/private static String create_timestamp() {return Long.toString(System.currentTimeMillis() / 1000);} }

網絡工具類.java

import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UrlPathHelper;import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.util.Map;/*** @program:gzdm* @author:wihenne* @creatTime:2021/05/06**/ @Component public class HttpUtil {//發起GET請求public String GETclient(String url, Map<String, Object> map) {RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);String result = restTemplate.getForObject(url, String.class, map);return result;}//發起POST請求,獲取圖片字節public byte[] getCodeImgBytes(String url,Map<String,Object> param){RestTemplate restTemplate = new RestTemplate();MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();HttpEntity requestEntity = new HttpEntity(param, headers);ResponseEntity<byte[]> entity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);byte[] result = entity.getBody();return result;}/*** 獲得當前訪問的URL路徑* @param request* @return*/public static String getLocation(HttpServletRequest request) {UrlPathHelper helper = new UrlPathHelper();StringBuffer buff = request.getRequestURL();String uri = request.getRequestURI();String origUri = helper.getOriginatingRequestUri(request);buff.replace(buff.length() - uri.length(), buff.length(), origUri);String queryString = helper.getOriginatingQueryString(request);if (queryString != null) {buff.append("?").append(queryString);}try {return new String(buff.toString().getBytes(), "iso-8859-1");} catch (UnsupportedEncodingException e) {return buff.toString();}} }

controler交互

/*** 獲取wechatConfig信息* @param url 訪問頁面的地址* @return*/@GetMapping("/getWechatConfig")public Map<String,String> getWechatConfig(String url){return wechatUtil.wxConfig(url);}

js

//將url 存進緩存下 var url = "https://" + window.location.host; var urlCureent = encodeURIComponent(location.href); $.ajax({async:true,dataType:"json",type:"GET",url: url + "/verification/getWechatConfig?url=" + urlCureent,contentType: "application/json; charset=utf-8",success:function(data){wx.config({debug: 0,appId: data.appId,timestamp: data.timestamp,nonceStr: data.nonceStr,signature: data.signature,jsApiList: ["updateAppMessageShareData", "updateTimelineShareData","onMenuShareTimeline","onMenuShareAppMessage"]});wx.ready(function () { //需在用戶可能點擊分享按鈕前就先調用wx.updateAppMessageShareData({title: cardVo.cardName + "個人名片", // 分享標題desc: cardVo.cardNameEn + "'s card", // 分享描述link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標success: function () {console.log("success");// 設置成功}});wx.updateTimelineShareData({title: cardVo.cardName + "個人名片", // 分享標題link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標success: function () {console.log("success2");// 設置成功}});wx.onMenuShareTimeline({title: cardVo.cardName + "個人名片", // 分享標題desc: cardVo.cardNameEn + "'s card", // 分享描述link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標});wx.onMenuShareAppMessage({title: cardVo.cardName + "個人名片", // 分享標題link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: url + cardVo.cardImg, // 分享圖標});});}});

常見問題

獲取JSSDK權限成功但分享無效果

官方建議使用wx.updateAppMessageShareData、wx.updateTimelineShareData,但是我當時無效果,再加上舊版本接口wx.onMenuShareTimeline、wx.onMenuShareAppMessage就可以了。

本地調試無效果

本地調試需要ngrok等外網穿透再做白名單

微信頁面緩存

微信緩存機制,在js后面加個版本號即可。

<script type="text/javascript">var js = document.getElementById('cardJs');js.src = './gzdm/card.js?v='+ new Date().getTime();var css = document.getElementById('cardCss');css.href = './css/card.css?v='+ new Date().getTime(); </script>

總結

以上是生活随笔為你收集整理的微信自定义分享链接内容,wx.updateAppMessageShareData、wx.updateTimelineShareData、wx.onMenuShareTimeline的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。