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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

手把手带你使用JS-SDK自定义微信分享效果

發布時間:2025/6/17 javascript 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手把手带你使用JS-SDK自定义微信分享效果 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

剛進入一家新公司,接到的第一個任務就是需要需要自定義微信分享的效果(自定義縮略圖,標題,摘要),一開始真是一臉懵逼,在網上搜索了半天之后大概有了方案。值得注意的是一開始搜索到的解決方案全是調用微信的自帶的JS-SDK,然而騰訊是不會讓廣大吃瓜群眾這么輕而易舉的調用他們的東西的。微信開發團隊已經把調用的權限收回,現在無法直接在頁面直接調用JS-SDK了。話不多說,直接上干貨。

預期效果

原始的分享效果:

?

使用微信JS-SDK的分享效果:

可以看出縮略圖,標題,摘要樣式良好,給用戶的體驗很好。

準備工作

微信官方開發者文檔地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

現在的思路已經很明確了,就是通過調用微信的JS-SDK實現自定義分享效果。但是這個調用過程比較繁瑣,需要提前準備如下東西:

(1)微信服務號一個,并且已經通過了實名認證;

   沒有實名認證的話,一些接口沒有調用權限。

(2)一個ICP備案的域名;

這個域名需要設置為微信公眾號后臺的JS接口安全域名,否則微信仍然不允許調用它的接口。

這時大家應該就犯難了,這樣的話豈不是不能在本地測試,只能部署到生產環境才能測試?不用著急,解決方案告訴大家:花生殼的內網穿透服務(收費,20元以內)

花生殼官網:http://hsk.oray.com/price/#personal

選擇個人免費版就可以了,雖然說是免費版,但是其實注冊過程中還是要收幾塊錢的,因為我自己買了域名和流量所以花的錢更多一些,但也在20元以內。不建議大家購買流量,送的流量可以用很久了。

當準備好上面提到的就可以開始敲代碼了。

(3)安裝微信開發者工具,用于本地調試。

下載地址:https://mp.weixin.qq.com/debug/cgi-bin/webdebugger/download?from=mpwiki&os=x64

官方使用教程:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455784140

具體步驟

(1)查看AppId,AppSecret以及綁定域名

進入微信后臺,找到下面的菜單

獲取AppID和AppSecret

設置JS接口安全域名

?

?

注意第三步,如果微信服務器不能在我們的服務器上訪問到這個txt文件,域名是無法設置成功的,這里先告訴大家在哪里設置,想要成功設置域名還需要使用花生殼的服務,讓微信服務器訪問我們本地工程中的的txt文件才行。

hkh3321313.vicp.io是在花生殼上購買的域名,免費送的域名是在太難記了,完全不能忍。

?

(2)引入JS文件

這里需要注意是http還是https,如果生產環境是https,務必前綴是https,都則會出現mix content這樣的錯誤,導致引入失敗。

<script typet="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

?

(3)通過AppId和AppSecret請求accessToken,然后通過accessToken獲取jsapi_ticket,生成config接口所需參數

因為獲取這兩個參數的次數是有限制的(accessToke 每日2000次,jsapi_ticket 每日100000次),有效期是7200秒,每兩小時請求一次就行啦,把獲取的accessToke和jsapi_ticket保存在后臺,所以accessToken和jsapi_ticket這兩個參數的獲取是通過ajax方式請求后臺,而不是實時去獲取的。

config幾個參數需要詳細說明一下:

  • timestamp? 生成簽名的時間戳? create_nonce_str()
  • nonceStr? 隨機生成的字符串 create_timestamp()
  • signature? 按照微信文檔簽名算法生成的簽名 makeWXTicket()
  • 附上signature算法的官方說明:

    https://mp.weixin.qq.com/wiki?action=doc&id=mp1421141115&t=0.15697429783636763#buzhou3

    在附錄1中可以找到詳細說明。

    此外,官方提供了一個簽名算法的校驗工具:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

    下面只附上了主要的方法:

    //獲取accessToken private JSONObject getAccessToken(){//String accessTokenUrl= https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRETString requestUrl = accessTokenUrl.replace("APPID",appId).replace("APPSECRET",appSecret);log.info("getAccessToken.requestUrl====>"+requestUrl);JSONObject result = HttpUtil.doGet(requestUrl);return result ; }//獲取ticket private JSONObject getJsApiTicket(){//String apiTicketUrl= https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapiString requestUrl = apiTicketUrl.replace("ACCESS_TOKEN", accessToken);log.info("getJsApiTicket.requestUrl====>"+requestUrl);JSONObject result = HttpUtil.doGet(requestUrl);return result; }//生成微信權限驗證的參數 public Map<String, String> makeWXTicket(String jsApiTicket, String url) {Map<String, String> ret = new HashMap<String, String>();String nonceStr = createNonceStr();String timestamp = createTimestamp();String string1;String signature = "";//注意這里參數名必須全部小寫,且必須有序string1 = "jsapi_ticket=" + jsApiTicket +"&noncestr=" + nonceStr +"&timestamp=" + timestamp +"&url=" + url;log.info("String1=====>"+string1);try{MessageDigest crypt = MessageDigest.getInstance("SHA-1");crypt.reset();crypt.update(string1.getBytes("UTF-8"));signature = byteToHex(crypt.digest());log.info("signature=====>"+signature);}catch (NoSuchAlgorithmException e){log.error("WeChatController.makeWXTicket=====Start");log.error(e.getMessage(),e);log.error("WeChatController.makeWXTicket=====End");}catch (UnsupportedEncodingException e){log.error("WeChatController.makeWXTicket=====Start");log.error(e.getMessage(),e);log.error("WeChatController.makeWXTicket=====End");}ret.put("url", url);ret.put("jsapi_ticket", jsApiTicket);ret.put("nonceStr", nonceStr);ret.put("timestamp", timestamp);ret.put("signature", signature);ret.put("appid", 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; } //生成隨機字符串 private static String createNonceStr() {return UUID.randomUUID().toString(); } //生成時間戳 private static String createTimestamp() {return Long.toString(System.currentTimeMillis() / 1000); }

    HttpUtil代碼

    public class HttpUtil {public static Log logger = LogFactory.getLog(HttpUtil.class);//get請求 public static com.alibaba.fastjson.JSONObject doGet(String requestUrl) {CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String responseContent = null;com.alibaba.fastjson.JSONObject result = null;try {//創建Get請求,HttpGet httpGet = new HttpGet(requestUrl);//執行Get請求,response = httpClient.execute(httpGet);//得到響應體HttpEntity entity = response.getEntity();//獲取響應內容responseContent = EntityUtils.toString(entity,"UTF-8");//轉換為mapresult = JSON.parseObject(responseContent);} catch (IOException e) {logger.error("HttpUtil=====Start");logger.error(e.getMessage(),e);logger.error("HttpUtil=====End");}return result;} }

    ?

    (4)通過config接口注入權限驗證配置

    官方示例:

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

    自己的代碼:

    其中的url不能硬編碼寫在后臺,必須通過動態傳遞。

    $(function(){var url = location.href.split('#').toString();//url不能寫死 $.ajax({type : "get",url : "/wechatParam",dataType : "json",async : false,data:{url:url},success : function(data) {wx.config({debug: false,////生產環境需要關閉debug模式appId: data.appid,//appId通過微信服務號后臺查看timestamp: data.timestamp,//生成簽名的時間戳nonceStr: data.nonceStr,//生成簽名的隨機字符串signature: data.signature,//簽名jsApiList: [//需要調用的JS接口列表'checkJsApi',//判斷當前客戶端版本是否支持指定JS接口'onMenuShareTimeline',//分享給好友'onMenuShareAppMessage'//分享到朋友圈 ]});},error: function(xhr, status, error) {//alert(status);//alert(xhr.responseText); }}) });

    ?

    (5)通過ready接口處理成功驗證

    官方示例:

    wx.ready(function(){// config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對于用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。 });

    自己的代碼:

    wx.ready(function () {var link = window.location.href;var protocol = window.location.protocol;var host = window.location.host;//分享朋友圈 wx.onMenuShareTimeline({title: '這是一個自定義的標題!',link: link,imgUrl: protocol+'//'+host+'/resources/images/icon.jpg',// 自定義圖標trigger: function (res) {// 不要嘗試在trigger中使用ajax異步請求修改本次分享的內容,因為客戶端分享操作是一個同步操作,這時候使用ajax的回包會還沒有返回.//alert('click shared'); },success: function (res) {//alert('shared success');//some thing you should do },cancel: function (res) {//alert('shared cancle'); },fail: function (res) {//alert(JSON.stringify(res)); }});//分享給好友 wx.onMenuShareAppMessage({title: '這是一個自定義的標題!', // 分享標題desc: '這是一個自定義的描述!', // 分享描述link: link, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致imgUrl: protocol+'//'+host+'/resources/images/icon.jpg', // 自定義圖標type: 'link', // 分享類型,music、video或link,不填默認為linkdataUrl: '', // 如果type是music或video,則要提供數據鏈接,默認為空success: function () {// 用戶確認分享后執行的回調函數 },cancel: function () {// 用戶取消分享后執行的回調函數 }});wx.error(function (res) {alert(res.errMsg);});});

    到這里所有的代碼都已經分享完畢了。

    ?

    (6)啟動花生殼的內網穿透服務,設置JS接口安全域名

    這個基本是傻瓜式的,只要下載他們的客戶端就可以了。

    官網教程:http://hsk.oray.com/news/4345.html

    添加一個映射就可以了

    把之前下載的txt文件放在工程目錄webapp下,然后本地啟動工程,確定通過域名可以訪問本地項目后,設置JS安全域名

    現在訪問 域名:端口號(例如:hkh3321313.vicp.io:8080)就可以訪問本地項目啦。

    ?

    (7)使用微信開發者工具測試

    微信開發者工具其實就是微信的瀏覽器,其中集成了chrome的調試工具,前面提到wx.config中的debug模式這里就發揮作用了,瀏覽器會自動彈出調用微信接口的返回結果。

    成功返回的話結果應該是ok什么的,圖就不上了。提醒大家,上生產環境一定要把debug改為false~

    ?

    后記

    ?雖然已經給了主要的代碼,大家一定還是不想寫接口,下面附上完整的代碼,如果你覺得解了燃眉之急,就點個頂吧,哈哈哈~

    @Controller public class WeChatController {private final Logger log = LoggerFactory.getLogger(this.getClass());//獲取相關的參數,在application.properties文件中@Value("${wechat.appId}")private String appId;@Value("${wechat.appSecret}")private String appSecret;@Value("${wechat.url.accessToken}")private String accessTokenUrl;@Value("${wechat.url.apiTicket}")private String apiTicketUrl;//微信參數 private String accessToken;private String jsApiTicket;//獲取參數的時刻private Long getTiketTime = 0L;private Long getTokenTime = 0L;//參數的有效時間,單位是秒(s)private Long tokenExpireTime = 0L;private Long ticketExpireTime = 0L;//獲取微信參數@RequestMapping("/wechatParam")@ResponseBodypublic Map<String, String> getWechatParam(String url){//當前時間long now = System.currentTimeMillis();log.info("currentTime====>"+now+"ms");//判斷accessToken是否已經存在或者token是否過期if(StringUtils.isBlank(accessToken)||(now - getTokenTime > tokenExpireTime*1000)){JSONObject tokenInfo = getAccessToken();if(tokenInfo != null){log.info("tokenInfo====>"+tokenInfo.toJSONString());accessToken = tokenInfo.getString("access_token");tokenExpireTime = tokenInfo.getLongValue("expires_in");//獲取token的時間getTokenTime = System.currentTimeMillis();log.info("accessToken====>"+accessToken);log.info("tokenExpireTime====>"+tokenExpireTime+"s");log.info("getTokenTime====>"+getTokenTime+"ms");}else{log.info("====>tokenInfo is null~");log.info("====>failure of getting tokenInfo,please do some check~");}}//判斷jsApiTicket是否已經存在或者是否過期if(StringUtils.isBlank(jsApiTicket)||(now - getTiketTime > ticketExpireTime*1000)){JSONObject ticketInfo = getJsApiTicket();if(ticketInfo!=null){log.info("ticketInfo====>"+ticketInfo.toJSONString());jsApiTicket = ticketInfo.getString("ticket");ticketExpireTime = ticketInfo.getLongValue("expires_in");getTiketTime = System.currentTimeMillis();log.info("jsApiTicket====>"+jsApiTicket);log.info("ticketExpireTime====>"+ticketExpireTime+"s");log.info("getTiketTime====>"+getTiketTime+"ms");}else{log.info("====>ticketInfo is null~");log.info("====>failure of getting tokenInfo,please do some check~");}}//生成微信權限驗證的參數Map<String, String> wechatParam= makeWXTicket(jsApiTicket,url);return wechatParam;}//獲取accessToken private JSONObject getAccessToken(){//String accessTokenUrl = https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRETString requestUrl = accessTokenUrl.replace("APPID",appId).replace("APPSECRET",appSecret);log.info("getAccessToken.requestUrl====>"+requestUrl);JSONObject result = HttpUtil.doGet(requestUrl);return result ;}//獲取ticket private JSONObject getJsApiTicket(){//String apiTicketUrl = https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapiString requestUrl = apiTicketUrl.replace("ACCESS_TOKEN", accessToken);log.info("getJsApiTicket.requestUrl====>"+requestUrl);JSONObject result = HttpUtil.doGet(requestUrl);return result;}//生成微信權限驗證的參數public Map<String, String> makeWXTicket(String jsApiTicket, String url) {Map<String, String> ret = new HashMap<String, String>();String nonceStr = createNonceStr();String timestamp = createTimestamp();String string1;String signature = "";//注意這里參數名必須全部小寫,且必須有序string1 = "jsapi_ticket=" + jsApiTicket +"&noncestr=" + nonceStr +"&timestamp=" + timestamp +"&url=" + url;log.info("String1=====>"+string1);try{MessageDigest crypt = MessageDigest.getInstance("SHA-1");crypt.reset();crypt.update(string1.getBytes("UTF-8"));signature = byteToHex(crypt.digest());log.info("signature=====>"+signature);}catch (NoSuchAlgorithmException e){log.error("WeChatController.makeWXTicket=====Start");log.error(e.getMessage(),e);log.error("WeChatController.makeWXTicket=====End");}catch (UnsupportedEncodingException e){log.error("WeChatController.makeWXTicket=====Start");log.error(e.getMessage(),e);log.error("WeChatController.makeWXTicket=====End");}ret.put("url", url);ret.put("jsapi_ticket", jsApiTicket);ret.put("nonceStr", nonceStr);ret.put("timestamp", timestamp);ret.put("signature", signature);ret.put("appid", 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;}//生成隨機字符串 private static String createNonceStr() {return UUID.randomUUID().toString();}//生成時間戳 private static String createTimestamp() {return Long.toString(System.currentTimeMillis() / 1000);} }

    ?

    轉載于:https://www.cnblogs.com/backtozero/p/7064247.html

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的手把手带你使用JS-SDK自定义微信分享效果的全部內容,希望文章能夠幫你解決所遇到的問題。

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