如何在微信6.0.2+版本不接入微信API的情況下設置自定義分享內容
如何在微信6.0.2+版本不接入微信API的情況下設置自定義分享內容(圖片、鏈接、標題)
微信在6.0.2及以上版本已經回收客戶端自定分享的權限,而是以授權api的形式開放出來。有時候我們只想簡單地自定義分享的title,分享的圖片以及分享的鏈接時,而不想或者缺乏資源去接入微信api的時候該怎么實現呢?
方法如下
1.設置分享title:動態改變document.title值即可:
document.title = 'test'
2.設置分享圖片:在頁面隱藏一張尺寸大于290*290的圖(圖片需要容器包裹,設置容器css屬性display:none即可):
<div style="display:none"><img src="share.jpg" /></div>
3.設置分享的鏈接:動態修改document.documentURI的值即可
document.documentURI = "http://navyxie.github.io/"
以上方法即可在微信6.0.2+版本自定義分享內容,不需額外引入微信的js文件
-----------------------------------------------------------華麗麗分割線-----------------------------------------------------------
接下來,帶大家通過解壓微信app(android),分析js源代碼來了解微信api的運行原理。
前期準備
- 下載微信app(android),下載地址: http://weixin.qq.com/cgi-bin/readtemplate?t=weixindownload list&lang=zh CN
- 將weixin APK重名名成.zip格式,然后解壓縮,在目錄/assets/jsapi/下找到文件wxjs.js,我已經這個文件放在github,大家可以直接查看 wxjs.js .這個就是我們要分析的文件了。
源碼閱讀與分析(目前微信Android最新版為6.2,我們以此為例子)
在微信6.0.2以前的版本,我們在做微信h5頁面上做分享時,還清晰地記得一段這樣的代碼嗎?
WeixinJSBridge.on('menu:share:timeline', function(argv) { // 分享到朋友圈
WeixinJSBridge.invoke('shareTimeline', {
"img_url": window.ShareData.img,
"link": window.ShareData.link,
"title": window.ShareData.TimelineTitle,
"desc": window.ShareData.TimelineTitle
}, function(res) {
window.ShareData.TimelineSuccess();
});
});
所以我們通過搜索關鍵字:link,title,desc可以輕松地找到設置分享內容的位置(會找到多個,因為分享的渠道很多,朋友圈,朋友等),我們找到分享到朋友圈那段設置分享內容的源代碼(2549-2578行):
// share timeline
_on('menu:share:timeline',function(argv){
_log('share timeline');
var data;
if (typeof argv.title === 'string') {
data = argv;
_call('shareTimeline',data);
}else{
data = {
// "img_url": "",
// "img_width": "",
// "img_height": "",
"link": document.documentURI || _session_data.init_url,
"desc": document.documentURI || _session_data.init_url,
"title": document.title
};
var shareFunc = function(_img){
if (_img) {
data['img_url'] = _img.src;
data['img_width'] = _img.width;
data['img_height'] = _img.height;
}
_call('shareTimeline',data);
};
getSharePreviewImage(shareFunc);
}
});
我們可以看到,當參數argv帶有參數title時(通過調用微信api返回),會自然使用參數內容,否則title會使用document.title,desc會使用document.documentURI(當前頁面打開的鏈接),link同樣使用document.documentURI,那么自定圖片的代碼在哪里呢?上面代碼的最后的函數getSharePreviewImage 就是獲取頁面分享圖片的地址,我們追蹤到函數getSharePreviewImage里去(2467-2576行)
// 獲取頁面圖片算法:
// 在頁面中找到第一個最小邊大于290的圖片,如果1秒內找不到,則返回空(不帶圖分享)。
var getSharePreviewImage = function(cb){
var isCalled = false;
var callCB = function(_img){
if (isCalled) {return;};
isCalled = true;
cb(_img);
}
var _allImgs = _WXJS('img');
if (_allImgs.length==0) {
return callCB();
}
// 過濾掉重復的圖片
var _srcs = {};
var allImgs = [];
for (var i = 0; i < _allImgs.length; i++) {
var _img = _allImgs[i];
// 過濾掉不可以見的圖片
if (_WXJS(_img).css('display')=='none' || _WXJS(_img).css('visibility')=='hidden') {
// _log('ivisable image !! ' + _img.src);
continue;
}
if (_srcs[_img.src]) {
// added
} else {
_srcs[_img.src] = 1; // mark added
allImgs.push(_img);
}
};
var results = [];
var img;
for (var i = 0; i < allImgs.length && i < 100; i++) {
img = allImgs[i];
var newImg = new Image();
newImg.onload = function() {
this.isLoaded = true;
var loadedCount = 0;
for (var j = 0; j < results.length; j++) {
var res = results[j];
if (!res.isLoaded) {
break;
}
loadedCount++;
if (res.width>290 && res.height>290) {
callCB(res);
break;
}
}
if (loadedCount==results.length) {
// 全部都已經加載完了,但還是沒有找到。
callCB();
};
}
newImg.src = img.src;
results.push(newImg);
}
setTimeout(function(){
for (var j = 0; j < results.length; j++) {
var res = results[j];
if (!res.isLoaded) {
continue;
}
if (res.width>290 && res.height>290) {
callCB(res);
return;
}
}
callCB();
},1000);
}
閱讀上面代碼,真相終于浮出水面,看注釋:在頁面中找到第一個最小邊大于290的圖片,如果1秒內找不到,則返回空(不帶圖分享),所以當你需要設置自定義分享的圖片時,只需要在頁面中隱藏一張尺寸大于290*290的圖片即可(圖片不能太大,因為1秒鐘內如果加載不完這種圖會視為失敗,分享出去的內容就會不帶圖了,這也是為什么我們分享出去的內容有時候帶圖有時候不帶圖的原因)。
注意,設置分享的圖片必須包含在一個容器中,比如div,設置容器的css屬性,display:none即可,直接設置圖片display:none或者visibility:false,會被過濾掉,過濾代碼如下
// 過濾掉不可以見的圖片
if (_WXJS(_img).css('display')=='none' || _WXJS(_img).css('visibility')=='hidden') {
// _log('ivisable image !! ' + _img.src);
continue;
}
總結
- 當我們開發遇到問題時,最好的解決方法就是去閱讀閱代碼。
- 我嘗試著直接在browser模擬調用wxjs的api,會返回錯誤提示沒權限,微信在安全授權這一塊做得還是不錯滴
- 通過閱讀閱代碼,可以學習到很多知識,也能加深對該源代碼的了解,為后續解決問題默默做了積累
- 微信js內置了zepto的源代碼
- 微信webkit瀏覽器與native的通訊是通過創建一個隱藏的iframe,然后自定義通訊協議:weixin://。相信很多hybrid app 開發都在用這種方式。
- 當你需要使用其他微api時,比如獲取用戶授權信息,就需接微信api了。
小坑
- 自定義分享的圖片尺寸必須大于290*290,且必須由一個隱藏的容器包裹著
- 雖然我們可以在不接入weixin api的情況下自定義分享的title,link以及image,但是我們不能自定分享的描述內容(desc),默認使用了document.documentURI