1. 程式人生 > >關於微信二次分享,描述變連結的解決方法(一)----文件說明

關於微信二次分享,描述變連結的解決方法(一)----文件說明

前言:

最近工作中遇到了使用微信二次分享的時候,標題被截短,描述也變成了連結,圖片也沒有,運營人員半夜還在嚷嚷,無奈只好硬著頭皮去百度,去google,但是悲催的是沒有詳細的解決方法,最終只能自己去研究,還好最終搞出來了,決定分享一下,幫助需要的人。博文,分兩篇,第一篇主要是微信的官方文件說明,第二篇主要是程式碼部分;

一、微信JS-SDK說明文件

1.概述

微信JS-SDK是微信公眾平臺面向網頁開發者提供的基於微信內的網頁開發工具包。

通過使用微信JS-SDK,網頁開發者可藉助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信使用者提供更優質的網頁體驗。

此文件面向網頁開發者介紹微信JS-SDK如何使用及相關注意事項

2.JSSDK使用步驟

  2.1步驟一:繫結域名

  先登入微信公眾平臺進入“公眾號設定”的“功能設定”裡填寫“JS介面安全域名”,可以按照提示進行填寫,最多填寫三個。

  備註:登入後可在“開發者中心”檢視對應的介面許可權。

 

     2.2 步驟二:引入JS檔案

  備註:支援使用 AMD/CMD 標準模組載入方法載入

  2.3 步驟三:通過config介面注入許可權驗證配置

 所有需要使用JS-SDK的頁面必須先注入配置資訊,否則將無法呼叫(同一個url僅需呼叫一次,對於變化url的SPA的web app可在每次url變化時進行呼叫,目前Android微信客

     戶端不支援pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。

複製程式碼
wx.config({
    debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
    appId: '', // 必填,公眾號的唯一標識
    timestamp: , // 必填,生成簽名的時間戳
    nonceStr: '', // 必填,生成簽名的隨機串
    signature: '',// 必填,簽名,見附錄1
jsApiList: [] // 必填,需要使用的JS介面列表,所有JS介面列表見附錄2 });
複製程式碼

  2.4 步驟四:通過ready介面處理成功驗證

wx.ready(function(){

    // config資訊驗證後會執行ready方法,所有介面呼叫都必須在config介面獲得結果之後,config是一個客戶端的非同步操作,所以如果需要在頁面載入時就呼叫相關介面,則須把相關介面放在ready函式中呼叫來確保正確執行。對於使用者觸發時才呼叫的介面,則可以直接呼叫,不需要放在ready函式中。
});

  2.5 步驟五:通過error介面處理失敗驗證

複製程式碼
wx.error(function(res){

    // config資訊驗證失敗會執行error函式,如簽名過期導致驗證失敗,具體錯誤資訊可以開啟config的debug模式檢視,也可以在返回的res引數中檢視,對於SPA可以在這裡更新簽名。

});
複製程式碼

3.介面呼叫說明

  所有介面通過wx物件(也可使用jWeixin物件)來呼叫,引數是一個物件,除了每個介面本身需要傳的引數之外,還有以下通用引數:

  1. success:介面呼叫成功時執行的回撥函式。
  2. fail:介面呼叫失敗時執行的回撥函式。
  3. complete:介面呼叫完成時執行的回撥函式,無論成功或失敗都會執行。
  4. cancel:使用者點選取消時的回撥函式,僅部分有使用者取消操作的api才會用到。
  5. trigger: 監聽Menu中的按鈕點選時觸發的方法,該方法僅支援Menu中的相關介面。

  備註:不要嘗試在trigger中使用ajax非同步請求修改本次分享的內容,因為客戶端分享操作是一個同步操作,這時候使用ajax的回包會還沒有返回


  以上幾個函式都帶有一個引數,型別為物件,其中除了每個介面本身返回的資料之外,還有一個通用屬性errMsg,其值格式如下:

  1. 呼叫成功時:"xxx:ok" ,其中xxx為呼叫的介面名
  2. 使用者取消時:"xxx:cancel",其中xxx為呼叫的介面名
  3. 呼叫失敗時:其值為具體錯誤資訊

4.基礎介面(只列出了使用到的介面)

  4.1判斷當前客戶端版本是否支援指定JS介面(測試的時候使用很不錯)

備註:checkJsApi介面是客戶端6.0.2新引入的一個預留介面,第一期開放的介面均可不使用checkJsApi來檢測。

複製程式碼
wx.checkJsApi({
    jsApiList: ['chooseImage'], // 需要檢測的JS介面列表,所有JS介面列表見附錄2,
    success: function(res) {
        // 以鍵值對的形式返回,可用的api值true,不可用為false
        // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
    }
});
複製程式碼

5.分享介面

  5.1 獲取“分享到朋友圈”按鈕點選狀態及自定義分享內容介面

複製程式碼
wx.onMenuShareTimeline({
    title: '', // 分享標題
    link: '', // 分享連結
    imgUrl: '', // 分享圖示
    success: function () { 
        // 使用者確認分享後執行的回撥函式
    },
    cancel: function () { 
        // 使用者取消分享後執行的回撥函式
    }
});
複製程式碼

  5.2 獲取“分享給朋友”按鈕點選狀態及自定義分享內容介面

複製程式碼
wx.onMenuShareAppMessage({
    title: '', // 分享標題
    desc: '', // 分享描述
    link: '', // 分享連結
    imgUrl: '', // 分享圖示
    type: '', // 分享型別,music、video或link,不填預設為link
    dataUrl: '', // 如果type是music或video,則要提供資料鏈接,預設為空
    success: function () { 
        // 使用者確認分享後執行的回撥函式
    },
    cancel: function () { 
        // 使用者取消分享後執行的回撥函式
    }
});
複製程式碼

  5.3 獲取“分享到QQ”按鈕點選狀態及自定義分享內容介面

複製程式碼
wx.onMenuShareQQ({
    title: '', // 分享標題
    desc: '', // 分享描述
    link: '', // 分享連結
    imgUrl: '', // 分享圖示
    success: function () { 
       // 使用者確認分享後執行的回撥函式
    },
    cancel: function () { 
       // 使用者取消分享後執行的回撥函式
    }
});
複製程式碼

  5.4 獲取“分享到騰訊微博”按鈕點選狀態及自定義分享內容介面

複製程式碼
wx.onMenuShareWeibo({
    title: '', // 分享標題
    desc: '', // 分享描述
    link: '', // 分享連結
    imgUrl: '', // 分享圖示
    success: function () { 
       // 使用者確認分享後執行的回撥函式
    },
    cancel: function () { 
        // 使用者取消分享後執行的回撥函式
    }
});
複製程式碼

  5.5 獲取“分享到QQ空間”按鈕點選狀態及自定義分享內容介面

複製程式碼
wx.onMenuShareQZone({
    title: '', // 分享標題
    desc: '', // 分享描述
    link: '', // 分享連結
    imgUrl: '', // 分享圖示
    success: function () { 
       // 使用者確認分享後執行的回撥函式
    },
    cancel: function () { 
        // 使用者取消分享後執行的回撥函式
    }
});
複製程式碼

附錄1-JS-SDK使用許可權簽名演算法

  首先獲取jsapi_ticket

  生成簽名之前必須先了解一下jsapi_ticket,jsapi_ticket是公眾號用於呼叫微信JS介面的臨時票據。正常情況下,jsapi_ticket的有效期為7200秒

  通過access_token來獲取。由於獲取jsapi_ticket的api呼叫次數非常有限,頻繁重新整理jsapi_ticket會導致api呼叫受限,影響自身業務,

  開發者必須在自己的服務全域性快取jsapi_ticket 。

  成功返回如下JSON:

複製程式碼
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
複製程式碼

  獲得jsapi_ticket之後,就可以生成JS-SDK許可權驗證的簽名了。

  其次獲取簽名,簽名的演算法如下:

  簽名生成規則如下:參與簽名的欄位包括noncestr(隨機字串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其後面部分) 。

  對所有待簽名引數按照欄位名的ASCII 碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字串string1。

  這裡需要注意的是所有引數名均為小寫字元。對string1作sha1加密,欄位名和欄位值都採用原始值,不進行URL 轉義。

   即signature=sha1(string1)。 示例:

    noncestr=Wm3WZYTPz0wzccnW

    jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg

    timestamp=1414587457

url=http://mp.weixin.qq.com?params=value

  步驟1. 對所有待簽名引數按照欄位名的ASCII 碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字串string1:

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

  步驟2. 對string1進行sha1簽名,得到signature:

0f9de62fce790f9a083d5c99e95740ceb90c27ed

  注意事項

  1. 簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
  2. 簽名用的url必須是呼叫JS介面頁面的完整URL。
  3. 出於安全考慮,開發者必須在伺服器端實現簽名的邏輯

  如出現invalid signature 等錯誤詳見附錄5常見錯誤及解決辦法,開啟debug,如簽名無效會彈出invalid signature的提示

附錄2-所有JS介面列表

複製程式碼
版本1.0.0介面

onMenuShareTimeline
onMenuShareAppMessage
onMenuShareQQ
onMenuShareWeibo
onMenuShareQZone
startRecord
stopRecord
onVoiceRecordEnd
playVoice
pauseVoice
stopVoice
onVoicePlayEnd
uploadVoice
downloadVoice
chooseImage
previewImage
uploadImage
downloadImage
translateVoice
getNetworkType
openLocation
getLocation
hideOptionMenu
showOptionMenu
hideMenuItems
showMenuItems
hideAllNonBaseMenuItem
showAllNonBaseMenuItem
closeWindow
scanQRCode
chooseWXPay
openProductSpecificView
addCard
chooseCard
openCard
複製程式碼

附錄5-常見錯誤及解決方法

呼叫config 介面的時候傳入引數 debug: true 可以開啟debug模式,頁面會alert出錯誤資訊。以下為常見錯誤及解決方法:

  1. invalid url domain當前頁面所在域名與使用的appid沒有繫結,請確認正確填寫繫結的域名,如果使用了埠號,則配置的繫結域名也要加上埠號(一個appid可以繫結三個有效域名)
  2. invalid signature簽名錯誤。建議按如下順序檢查:
    1. 確認config中nonceStr(js中駝峰標準大寫S), timestamp與用以簽名中的對應noncestr, timestamp一致。
    2. 確認url是頁面完整的url(請在當前頁面alert(location.href.split('#')[0])確認),包括'http(s)://'部分,以及'?'後面的GET引數部分,但不包括'#'hash後面的部分。
    3. 確認 config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
    4. 確保一定快取access_token和jsapi_ticket。
    5. 確保你獲取用來簽名的url是動態獲取的,動態頁面可參見例項程式碼中php的實現方式。如果是html的靜態頁面在前端通過ajax將url傳到後臺簽名,前端需要用js獲取當前頁面除去'#'hash部分的連結(可用location.href.split('#')[0]獲取,而且需要encodeURIComponent),因為頁面一旦分享,微信客戶端會在你的連結末尾加入其它引數,如果不是動態獲取當前連結,將導致分享後的頁面簽名失敗
  3. the permission value is offline verifying這個錯誤是因為config沒有正確執行,或者是呼叫的JSAPI沒有傳入config的jsApiList引數中。建議按如下順序檢查:
    1. 確認config正確通過。
    2. 如果是在頁面載入好時就呼叫了JSAPI,則必須寫在wx.ready的回撥中。
    3. 確認config的jsApiList引數包含了這個JSAPI。
  4. permission denied該公眾號沒有許可權使用這個JSAPI,或者是呼叫的JSAPI沒有傳入config的jsApiList引數中(部分介面需要認證之後才能使用)。
  5. function not exist當前客戶端版本不支援該介面,請升級到新版體驗。
  6. 為什麼6.0.1版本config:ok,但是6.0.2版本之後不ok(因為6.0.2版本之前沒有做許可權驗證,所以config都是ok,但這並不意味著你config中的簽名是OK的,請在6.0.2檢驗是否生成正確的簽名以保證config在高版本中也ok。)
  7. 在iOS和Android都無法分享(請確認公眾號已經認證,只有認證的公眾號才具有分享相關介面許可權,如果確實已經認證,則要檢查監聽介面是否在wx.ready回撥函式中觸發)
  8. 服務上線之後無法獲取jsapi_ticket,自己測試時沒問題。(因為access_token和jsapi_ticket必須要在自己的伺服器快取,否則上線後會觸發頻率限制。請確保一定對token和ticket做快取以減少2次伺服器請求,不僅可以避免觸發頻率限制,還加快你們自己的服務速度。目前為了方便測試提供了1w的獲取量,超過閥值後,服務將不再可用,請確保在服務上線前一定全域性快取access_token和jsapi_ticket,兩者有效期均為7200秒,否則一旦上線觸發頻率限制,服務將不再可用)。
  9. uploadImage怎麼傳多圖(目前只支援一次上傳一張,多張圖片需等前一張圖片上傳之後再呼叫該介面)
  10. 沒法對本地選擇的圖片進行預覽(chooseImage介面本身就支援預覽,不需要額外支援)
  11. 通過a連結(例如先通過微信授權登入)跳轉到b連結,invalid signature簽名失敗(後臺生成簽名的連結為使用jssdk的當前連結,也就是跳轉後的b連結,請不要用微信登入的授權連結進行簽名計算,後臺簽名的url一定是使用jssdk的當前頁面的完整url除去'#'部分)
  12. 出現config:fail錯誤(這是由於傳入的config引數不全導致,請確保傳入正確的appId、timestamp、nonceStr、signature和需要使用的jsApiList)
  13. 如何把jsapi上傳到微信的多媒體資源下載到自己的伺服器(請參見文件中uploadVoice和uploadImage介面的備註說明)
  14. Android通過jssdk上傳到微信伺服器,第三方再從微信下載到自己的伺服器,會出現雜音(微信團隊已經修復此問題,目前後臺已優化上線)
  15. 繫結父級域名,是否其子域名也是可用的(是的,合法的子域名在繫結父域名之後是完全支援的)
  16. 在iOS微信6.1版本中,分享的圖片外鏈不顯示,只能顯示公眾號頁面內鏈的圖片或者微信伺服器的圖片,已在6.2中修復
  17. 是否需要對低版本自己做相容(jssdk都是相容低版本的,不需要第三方自己額外做更多工作,但有的介面是6.0.2新引入的,只有新版才可呼叫)
  18. 該公眾號支付簽名無效,無法發起該筆交易(請確保你使用的jweixin.js是官方線上版本,不僅可以減少使用者流量,還有可能對某些bug進行修復,拷貝到第三方伺服器中使用,官方將不對其出現的任何問題提供保障,具體支付簽名演算法可參考 JSSDK微信支付一欄
  19. 目前Android微信客戶端不支援pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題已在Android6.2中修復
  20. uploadImage在chooseImage的回撥中有時候Android會不執行,Android6.2會解決此問題,若需支援低版本可以把呼叫uploadImage放在setTimeout中延遲100ms解決
  21. require subscribe錯誤說明你沒有訂閱該測試號,該錯誤僅測試號會出現
  22. getLocation返回的座標在openLocation有偏差,因為getLocation返回的是gps座標,openLocation開啟的騰訊地圖為火星座標,需要第三方自己做轉換,6.2版本開始已經支援直接獲取火星座標
  23. 檢視公眾號(未新增): "menuItem:addContact"不顯示,目前僅有從公眾號傳播出去的連結才能顯示,來源必須是公眾號
  24. ICP備案資料同步有一天延遲,所以請在第二日繫結

其他:

1.最好把微信的js以及對應的配置放在前面

2.關於圖片不能正確獲取的問題:

一般情況下,只要配置沒問題,基本上就可以的,但是有時候,配置檔案的圖片明明給到了,但是那張分享圖片仍不是我們想要的效果,而是可能直接抓取了body裡面的第一張圖片,所以

處理方法就是:在body裡面最前面加入一張不影響頁面的圖片:

<div style=" overflow:hidden; width:0px; height:0; margin:0 auto; position:absolute; top:-800px;"><img src="http://pic4.nipic.com/20090907/1628220_101501018346_2.jpg"></div>

3.關於標題及描述獲取不正確的問題:

雖然配置裡面title,desc,都是完整的,但分享出去的結果還是錯誤的,所以最好在html的head裡面也加上title,及描述

<title>微信二次分享</title>
<meta name="keywords" content="微信二次分享" />
<meta name="description" content="獲取微信二次分享描述" />

 4.分享小技巧:

獲取“分享到朋友圈”按鈕點選狀態及自定義分享內容介面

複製程式碼
wx.onMenuShareTimeline({
    title: '', // 分享標題
    link: '', // 分享連結
    imgUrl: '', // 分享圖示
    success: function () { 
        // 使用者確認分享後執行的回撥函式
    },
    cancel: function () { 
        // 使用者取消分享後執行的回撥函式
    }
});
複製程式碼

由於分享到朋友圈,是沒有分享描述的,右邊的文字取的是title的值,所以為了右邊的文字能夠更好地展示我們需要傳達的資訊,我們可以把title的值換成描述的值