微信公眾號(hào)網(wǎng)頁(yè)分享功能開發(fā)的示例代碼
現(xiàn)在每天都可以看到很多微信分享的鏈接上面有網(wǎng)站或者商家的自定義的分享標(biāo)題,和分享鏈接的描述及分享出去的圖像,例如下面的分享出去的鏈接:
上面這個(gè)是微信的js-SDK頁(yè)面分享給微信好友在聊天列表中顯示的視覺(jué)效果。
微信JS-SDK Demo :這個(gè)是微信網(wǎng)頁(yè)分享出去的標(biāo)題。
微信JS-SDK,幫助第三方為用戶提供更優(yōu)質(zhì)的移動(dòng)web服務(wù):這個(gè)是被分享的這個(gè)頁(yè)面的分享描述。
微信圖標(biāo):這個(gè)就是自己網(wǎng)站或者自己自定義的圖像。
上面這個(gè)是微信官方網(wǎng)頁(yè)分享出去的定義描述,那么怎樣實(shí)現(xiàn)自己網(wǎng)站網(wǎng)頁(yè)的自定義分享的標(biāo)題,描述及分享出去的顯示圖片呢,下面就具體的來(lái)探討一下微信網(wǎng)頁(yè)第三方分享自定的實(shí)現(xiàn)方式。
關(guān)于微信網(wǎng)頁(yè)分享自定義主要有兩方面的工作需要我們來(lái)做,一是:分享頁(yè)面的js分享代碼的編寫,二是:微信分享網(wǎng)頁(yè)的鏈接地址簽名。
首先來(lái)看一下網(wǎng)頁(yè)的連接地址簽名,這個(gè)功能主要是在服務(wù)端來(lái)時(shí)實(shí)現(xiàn)。
第一步:基礎(chǔ)數(shù)據(jù)的準(zhǔn)備,需要如下數(shù)據(jù)信息:
APPID:微信公眾號(hào)的id; APP_SECRECT:公眾號(hào)號(hào)的密鑰。簽名的網(wǎng)站域名(這個(gè)建議配置在配置文件中)。
第二步:微信簽名數(shù)據(jù)的準(zhǔn)備:
appid,secret,url將這三個(gè)參數(shù)放入map中, 鍵值為:appid=微信公眾號(hào)的id,secret=APP_SECRECT,url=網(wǎng)站的域名+網(wǎng)頁(yè)的請(qǐng)求地址+請(qǐng)求的參數(shù)。
代碼的實(shí)現(xiàn)方式如下:
1. controller層的代碼實(shí)現(xiàn):
@RequestMapping("cover")
public String identifyCover(HttpServletRequest request, HttpServletResponse response)
//微信分享授權(quán)開始
String appId = ;//取項(xiàng)目中配置的公眾號(hào)id
String secret = ;//取項(xiàng)目中配置的公眾號(hào)密鑰
//例如我們有一個(gè)分享的鏈接為:http://test.weixinfwenx.cn/project/fenxiang.do?id=1&name=2;
//那么domainAddr = http://test.weixinfwenx.cn,這個(gè)可以動(dòng)態(tài)的配置在項(xiàng)目里,方便測(cè)試環(huán)境和生產(chǎn)
//域名的切換
String domainAddr = "";//項(xiàng)目中配置的網(wǎng)站的域名
//這個(gè)取的是鏈接上的參數(shù),例如在上面的這個(gè)鏈接中,id=1&name=2就是我們要?jiǎng)討B(tài)去的參數(shù),可能有人
//會(huì)想到,這個(gè)兩個(gè)參數(shù)直接寫在地址中不是挺簡(jiǎn)單的為啥還要?jiǎng)討B(tài)去獲取這個(gè)參數(shù)呢;在這里我們引出了一
//個(gè)微信二次分享的問(wèn)題,就是別人轉(zhuǎn)發(fā)的鏈接給你,然后你再轉(zhuǎn)發(fā)給別人,在你轉(zhuǎn)發(fā)給別人后這個(gè)鏈接的簽
//名就會(huì)失敗,為啥呢,因?yàn)榻?jīng)過(guò)再次轉(zhuǎn)發(fā)的鏈接,微信會(huì)自動(dòng)加上一些自己的參數(shù),這樣會(huì)導(dǎo)致頁(yè)面上微信
//分享的鏈接和簽名的鏈接不一致。直接導(dǎo)致自定義的標(biāo)題和鏈接描述,顯示失敗,失敗原因是微信默認(rèn)的在
//我們的分享鏈接上加上了&from=singlemessage。
String str = request.getQueryString();
Map<String, String> map = new HashMap<String, String>();
map.put("appid", appId);
map.put("secret", secret);
String url = domainAddr + "/project/fenxiang.do?"+str; map.put("url", url);
//這個(gè)地址是傳給頁(yè)面使用
request.setAttribute("fenxurl", url);
//開始微信分享鏈接簽名
Map<String, String> params = weixinService.weixinjsIntefaceSign(map);
request.setAttribute("params", params);
return "自己的頁(yè)面";
2.service層的實(shí)現(xiàn)代碼:
接口:
public interface weixinService{
/**
* @Title: weixinjsIntefaceSign
* @Description: 微信js接口授權(quán)
* @param map
* @return
* @return: Map<String,String>
*/
public Map<String,String> weixinjsIntefaceSign(Map<String,String> map);
接口實(shí)現(xiàn)類:
public class weixinServiceImpl implements weixinService{
public Map<String, String> weixinjsIntefaceSign(Map<String, String> map){
//查看緩存數(shù)據(jù)是否存在
String cacheAccess_token = jedis.get("access_token");
String cacheTicket = jedis.get("ticket");
//取出來(lái)為空的話則說(shuō)明cacheAccess_token緩存過(guò)期,重新獲取
if(null == cacheAccess_token){
///////////////////////////////start
//獲取cacheAccess_token
//這段代碼實(shí)際開發(fā)過(guò)程中要寫成一個(gè)方法,我這里為了演示方便寫在了一起。
StringBuffer buffer = new StringBuffer();
buffer.append("https://api.weixin.qq.com/cgi-bin/token?");
buffer.append("appid="+map.get("appid"));
buffer.append("&secret="+map.get("secret"));
buffer.append("&grant_type=client_credential");
String resultMsg = SendUtils.sendGet(buffer.toString(), "UTF-8");
///////////////////// end
JSONObject json = new JSONObject(resultMsg);
cacheAccess_token = json.getString("access_token");
jedis.set("access_token",cacheAccess_token, "NX", "EX", 3600);//單位是秒
}
//取出來(lái)為空的話則說(shuō)明cacheTicket緩存過(guò)期,重新獲取
if(null == cacheTicket){
////////////////////////// start
////獲得jsapi_ticket
StringBuffer buffer = new StringBuffer();
buffer.append("https://api.weixin.qq.com/cgi-bin/ticket/getticket?");
buffer.append("access_token="+access_token);
buffer.append("&type=jsapi");
String ticket = SendUtils.sendGet(buffer.toString(), "UTF-8");
///////////////////// end
JSONObject json2 = new JSONObject(ticket);
cacheTicket = json2.getString("ticket");
jedis.set("ticket",cacheTicket, "NX", "EX", 3600);//單位是秒
}
//生成簽名
SortedMap<Object,Object> params = new TreeMap<Object,Object>();
params.put("timestamp", Long.toString(new Date().getTime()/1000));
params.put("noncestr", this.CreateNoncestr());
params.put("jsapi_ticket",cacheTicket);
params.put("url",map.get("url"));//url地址
StringBuffer sb = new StringBuffer();
Set es = params.entrySet();
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
sb.append(k + "=" + v + "&");
}
String signStr = sb.toString().substring(0, sb.toString().length()-1);
String sign = Sha1.getSha1Sign(signStr);//簽名
Map<String, String> result = new HashMap<String,String>();
result.put("timestamp",(String)params.get("timestamp"));
result.put("noncestr", (String)params.get("noncestr"));
result.put("signature", sign);
result.put("appId",map.get("appid"));
return result;
return null;
}
private String CreateNoncestr() {
String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
String res = "";
for (int i = 0; i < 16; i++) {
Random rd = new Random();
res += chars.charAt(rd.nextInt(chars.length() - 1));
}
return res;
}
}
輔助工具類:
/**
*
* 加密工具類
*
*/
public class Sha1 {
public static String getSha1Sign(String decript) {
try {
MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
try {
digest.update(decript.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
// 字節(jié)數(shù)組轉(zhuǎn)換為 十六進(jìn)制 數(shù)
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
http請(qǐng)求工具類:
/**
* http請(qǐng)求工具類
*
*/
public class SendUtils {
public static String sendGet(String url,String charset){
//新建客戶端
HttpClient httpclient = new HttpClient();
GetMethod getMethod = new GetMethod(url);
httpclient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);
httpclient.executeMethod(getMethod);
String responseMsg = getMethod.getResponseBodyAsString();
return responseMsg;
}
}
以上是服務(wù)器端的微信簽名的實(shí)現(xiàn)代碼,下面介紹一下分享頁(yè)面中js的編寫。
第一步引入微信的js文件:
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
第二步:
wx.config({
debug: false,
appId: '${params.appId}',
timestamp: '${params.timestamp}',
nonceStr: '${params.noncestr}',
signature:'${params.signature}',
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.ready(function(){
wx.checkJsApi({
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
wx.checkJsApi({
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
/*分享到朋友圈*/
wx.onMenuShareTimeline({
title: '計(jì)劃書', // 分享標(biāo)題
desc: '保險(xiǎn)讓生活更美好!', // 分享描述
link: '${fenxurl}', // 分享鏈接
imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享圖標(biāo)
success: function () {
// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
},
cancel: function () {
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
}
});
/*分享給朋友*/
wx.onMenuShareAppMessage({
title: '計(jì)劃書', // 分享標(biāo)題
desc: '保險(xiǎn)讓生活更美好!', // 分享描述
link: '${fenxurl}', // 分享鏈接
imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享圖標(biāo)
type: 'link', // 分享類型,music、video或link,不填默認(rèn)為link
dataUrl: '', // 如果type是music或video,則要提供數(shù)據(jù)鏈接,默認(rèn)為空
success: function () {
// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
alert("您已分享");
},
cancel: function () {
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
alert('您已取消分享');
}
});
wx.onMenuShareQQ({
title: '計(jì)劃書', // 分享標(biāo)題
desc: '保險(xiǎn)讓生活更美好!', // 分享描述
link: '${fenxurl}', // 分享鏈接
imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享圖標(biāo)
success: function () {
// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
},
cancel: function () {
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
}
});
wx.onMenuShareWeibo({
title: '計(jì)劃書', // 分享標(biāo)題
desc: '保險(xiǎn)讓生活更美好!', // 分享描述
link: '${fenxurl}', // 分享鏈接
imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享圖標(biāo)
success: function () {
// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
},
cancel: function () {
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
}
});
wx.onMenuShareQZone({
title: '計(jì)劃書', // 分享標(biāo)題
desc: '保險(xiǎn)讓生活更美好!', // 分享描述
link: '${fenxurl}', // 分享鏈接
imgUrl: '${params.urlg}/PF_IDENTIFY/Cacheable/image/business/plan-cover/product_img.png', // 分享圖標(biāo)
success: function () {
// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
},
cancel: function () {
// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
}
});
});
至此整個(gè)微信的整個(gè)分享開發(fā)完成,上面的這些js文件,都必須放在頁(yè)面上。
到此這篇關(guān)于微信公眾號(hào)網(wǎng)頁(yè)分享功能開發(fā)的示例代碼的文章就介紹到這了,更多相關(guān)微信公眾號(hào)網(wǎng)頁(yè)分享內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS圖片定時(shí)翻滾效果實(shí)現(xiàn)方法
這篇文章主要介紹了JS圖片定時(shí)翻滾效果實(shí)現(xiàn)方法,涉及javascript結(jié)合時(shí)間函數(shù)實(shí)現(xiàn)頁(yè)面元素動(dòng)態(tài)切換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
使用Fetch API時(shí)獲取404錯(cuò)誤的解決方案
在現(xiàn)代Web開發(fā)中,Fetch API 是用于執(zhí)行網(wǎng)絡(luò)請(qǐng)求的主要工具之一,它提供了一種基于Promise的簡(jiǎn)潔語(yǔ)法,使得異步操作更加直觀和易于管理,本文將詳細(xì)探討在使用Fetch API時(shí)獲取404錯(cuò)誤的原因、如何檢測(cè)和處理這些錯(cuò)誤,以及最佳實(shí)踐,需要的朋友可以參考下2024-12-12
JS實(shí)現(xiàn)根據(jù)用戶輸入分鐘進(jìn)行倒計(jì)時(shí)功能
倒計(jì)時(shí)功能大家無(wú)論在各大網(wǎng)站都可以看到,今天小編給大家分享一段基于js實(shí)現(xiàn)的根據(jù)用戶輸入分鐘進(jìn)行倒計(jì)時(shí)功能,非常不錯(cuò),需要的朋友參考下吧2016-11-11
小程序?qū)崿F(xiàn)人臉識(shí)別功能(百度ai)
這篇文章主要介紹了小程序?qū)崿F(xiàn)人臉識(shí)別功能(百度ai),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
微信小程序按鈕點(diǎn)擊動(dòng)畫效果的實(shí)現(xiàn)
這篇文章主要介紹了微信小程序按鈕點(diǎn)擊動(dòng)畫效果的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09
AJAX 網(wǎng)頁(yè)保留瀏覽器前進(jìn)后退等功能
AJAX的應(yīng)用較少了頁(yè)面的刷新次數(shù),但是也可能會(huì)使瀏覽器的前進(jìn)、后退、刷新等功能受到影響。2011-02-02
bootstrap paginator分頁(yè)前后臺(tái)用法示例
這篇文章主要為大家詳細(xì)介紹了bootstrap paginator分頁(yè)前后臺(tái)用法示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
JavaScript Perfection kill 測(cè)試及答案
近日,在Perfection kill上看到有關(guān)javascript quiz。并做了一下,最終錯(cuò)了2個(gè)(#2,#9),但是,這2道題,在Ie和ff下的答案是不一樣的?!2010-03-03

