微信內(nèi) H5 頁面自定義分享

起源:

最近公司在做一個活動的h5頁面,在微信內(nèi)打開時需要進(jìn)行微信授權(quán)粘姜,然后后端會重定向到這個頁面并且攜帶了一些參數(shù)(openid等)宰翅。問題是點擊微信的原生分享時穴墅,會把攜帶的這些參數(shù)一起分享出去霎迫,等于把用戶信息泄露了斋枢。所以為了解決這個問題,只能實現(xiàn)自定義微信分享的功能知给,可以自定義分享的地址瓤帚、標(biāo)題、圖標(biāo)還有簡介。

事先需要做的:

1.微信公眾號:必須是經(jīng)過微信認(rèn)證的缘滥,沒有認(rèn)證的或者認(rèn)證過期的都不可以轰胁;

2.經(jīng)過備案的域名:必須是備案過的谒主,不然是無法使用的朝扼;

3.綁定域名:首先你需要將需要分享的網(wǎng)址的域名綁定到微信公眾平臺上面,

具體操作:先登錄微信公眾平臺進(jìn)入“公眾號設(shè)置”的“功能設(shè)置”里填寫:JS接口安全域名霎肯;還要在"安全中心"中設(shè)置:IP白名單


904df06155fe1efcb0dbd63e12c11e99.png

4d7207fc806747794e2033fc35aa5232.png
后臺需要做的:

1.后臺服務(wù)器:前臺頁面需要后臺服務(wù)器傳過來一些配置參數(shù)擎颖,比如appId、timestamp观游、nonceStr搂捧、signature這幾個參數(shù)都是后臺從微信公眾平臺獲取到的, 需要后臺進(jìn)行配合懂缕;

2.獲取access_token:利用公共號APPID允跑、APPSECRET從微信服務(wù)器獲取對應(yīng)的access_token,這里是后臺開發(fā)小伙伴的范圍不多做解釋搪柑;

后臺需要傳的參數(shù)格式:

[圖片上傳失敗...(image-b9822e-1622797016151)]
簽名的生成步驟:

生成簽名之前必須先了解一下jsapi_ticket聋丝,jsapi_ticket是公眾號用于調(diào)用微信JS接口的臨時票據(jù)。正常情況下工碾,jsapi_ticket的有效期為7200秒弱睦,通過access_token來獲取。由于獲取jsapi_ticket的api調(diào)用次數(shù)非常有限渊额,頻繁刷新jsapi_ticket會導(dǎo)致api調(diào)用受限况木,影響自身業(yè)務(wù),開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket 旬迹。

  1. 獲取access_token(有效期7200秒火惊,2個小時開發(fā)者必須在自己的服務(wù)全局緩存access_token):access_token是公眾號的全局唯一接口調(diào)用憑據(jù),公眾號調(diào)用各接口時都需使用access_token奔垦。開發(fā)者需要進(jìn)行妥善保存屹耐。具體請參考以下官方文檔:

https://link.zhihu.com/?target=https%3A//developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

公眾號和小程序均可以使用AppID和AppSecret調(diào)用本接口來獲取access_token。AppID和AppSecret可在“微信公眾平臺-開發(fā)-基本配置”頁中獲得(需要已經(jīng)成為開發(fā)者宴倍,且?guī)ぬ枦]有異常狀態(tài))张症。調(diào)用接口時,請登錄“微信公眾平臺-開發(fā)-基本配置”提前將服務(wù)器IP地址添加到IP白名單中鸵贬,點擊查看設(shè)置方法俗他,否則將無法調(diào)用成功。小程序無需配置IP白名單阔逼。示例代碼如下所示:

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

返回的JSON如下:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
  1. 用第一步拿到的access_token 采用http GET方式請求獲得jsapi_ticket(有效期7200秒兆衅,2個小時,開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket)
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回JSON如下:

{
  "errcode":0,
  "errmsg":"ok",
  "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
  "expires_in":7200
}
  1. 生成JS-SDK權(quán)限驗證的簽名

參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分) 羡亩。

首先:對所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后摩疑,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1:

順序依次為:jsapi_ticket,noncestr畏铆,timestamp雷袋,url。

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

然后:對string1進(jìn)行sha1簽名辞居,得到signature楷怒。

signature=sha1(string1) // 0f9de62fce790f9a083d5c99e95740ceb90c27ed

注意事項

簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
簽名用的url必須是調(diào)用JS接口頁面的完整URL瓦灶。
出于安全考慮鸠删,開發(fā)者必須在服務(wù)器端實現(xiàn)簽名的邏輯。

前端需要做的:

參考官方文檔:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

1贼陶、在項目中引用微信的js-sdk

官方文檔上寫的是1.6.0

在需要調(diào)用JS接口的頁面引入如下JS文件刃泡,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js

如需進(jìn)一步提升服務(wù)穩(wěn)定性,當(dāng)上述資源不可訪問時烘贴,可改訪問:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)眨层。

2馒闷、配置config

所有需要使用JS-SDK的頁面必須先注入配置信息纳账,否則將無法調(diào)用疏虫。同一個url僅需調(diào)用一次卧秘,對于變化url的SPA的web app可在每次url變化時進(jìn)行調(diào)用翅敌。其中的簽名信息signature需要服務(wù)器端提供蚯涮。timestamp和nonceStr是參與簽名生成的字段遭顶,因此也可以由服務(wù)端一并提供,代碼如下所示:

wx.config({
    debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來喘批,若要查看傳入的參數(shù)嗦哆,可以在pc端打開老速,參數(shù)信息會通過log打出凸主,僅在pc端時才會打印旁舰。
    appId: '', 
    timestamp: , 
    nonceStr: '', 
    signature: '',
    jsApiList: [] 
});

參數(shù)說明:
appId:公眾號的唯一標(biāo)識箭窜,在公眾號中可以取到;
timestamp:生成簽名的時間戳
nonceStr:生成簽名的隨機串
signature:最后生成的簽名
jsApiList:需要使用的JS接口列表竹捉,我們這里是用分享接口块差,將分享幾個api接口填進(jìn)去憨闰,例如:['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareQQ']

3鹉动、通過ready接口處理成功驗證

wx.ready(function(){
  // config信息驗證通過后會執(zhí)行ready方法,
  // 所有接口調(diào)用都必須在config接口獲得結(jié)果之后警儒,
  // config是一個客戶端的異步操作眶根,所以如果需要在頁面加載時就調(diào)用相關(guān)接口边琉,
  // 則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。
  // 對于用戶觸發(fā)時才調(diào)用的接口变姨,則可以直接調(diào)用族扰,不需要放在ready函數(shù)中。
});

4渔呵、通過error接口處理失敗驗證

wx.error(function(res){
  // config信息驗證失敗會執(zhí)行error函數(shù)砍鸠,
  // 如簽名過期導(dǎo)致驗證失敗爷辱,具體錯誤信息可以打開config的debug模式查看双饥,
  // 也可以在返回的res參數(shù)中查看,對于SPA可以在這里更新簽名。
});

所有接口通過wx對象(也可使用jWeixin對象)來調(diào)用昏翰,參數(shù)是一個對象,除了每個接口本身需要傳的參數(shù)之外舍咖,還有以下通用參數(shù):

success:接口調(diào)用成功時執(zhí)行的回調(diào)函數(shù)矩父。
fail:接口調(diào)用失敗時執(zhí)行的回調(diào)函數(shù)。
complete:接口調(diào)用完成時執(zhí)行的回調(diào)函數(shù)排霉,無論成功或失敗都會執(zhí)行窍株。
cancel:用戶點擊取消時的回調(diào)函數(shù),僅部分有用戶取消操作的api才會用到攻柠。
trigger:監(jiān)聽Menu中的按鈕點擊時觸發(fā)的方法球订,該方法僅支持Menu中的相關(guān)接口。

備注:不要嘗試在trigger中使用ajax異步請求修改本次分享的內(nèi)容瑰钮,因為客戶端分享操作是一個同步操作冒滩,這時候使用ajax的回包會還沒有返回。

以上幾個函數(shù)都帶有一個參數(shù)浪谴,類型為對象开睡,其中除了每個接口本身返回的數(shù)據(jù)之外因苹,還有一個通用屬性errMsg,其值格式如下:

調(diào)用成功時:"xxx:ok" 篇恒,其中xxx為調(diào)用的接口名

用戶取消時:"xxx:cancel"扶檐,其中xxx為調(diào)用的接口名

調(diào)用失敗時:其值為具體錯誤信息

官方示例代碼:

自定義“分享給微信朋友”及“分享到QQ好友”按鈕的分享內(nèi)容(JSSDK 1.4.0以上版本支持):

wx.ready(function () {   //需在用戶可能點擊分享按鈕前就先調(diào)用
  wx.updateAppMessageShareData({ 
    title: '', // 分享標(biāo)題
    desc: '', // 分享描述
    link: '', // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致
    imgUrl: '', // 分享圖標(biāo)
    success: function () {
      // 設(shè)置成功
    }
  })
}); 

自定義“分享到朋友圈”及“分享到QQ空間”按鈕的分享內(nèi)容(JSSDK 1.4.0以上版本支持):

wx.ready(function () {      //需在用戶可能點擊分享按鈕前就先調(diào)用
  wx.updateTimelineShareData({ 
    title: '', // 分享標(biāo)題
    link: '', // 分享鏈接胁艰,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致
    imgUrl: '', // 分享圖標(biāo)
    success: function () {
      // 設(shè)置成功
    }
  })
});

獲取“分享給朋友”按鈕點擊狀態(tài)及自定義分享內(nèi)容接口(即將廢棄):

wx.onMenuShareAppMessage({
  title: '', // 分享標(biāo)題
  desc: '', // 分享描述
  link: '', // 分享鏈接款筑,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致
  imgUrl: '', // 分享圖標(biāo)
  type: '', // 分享類型,music、video或link腾么,不填默認(rèn)為link
  dataUrl: '', // 如果type是music或video奈梳,則要提供數(shù)據(jù)鏈接,默認(rèn)為空
  success: function () {
    // 用戶點擊了分享后執(zhí)行的回調(diào)函數(shù)
  }
});

獲取“分享到朋友圈”按鈕點擊狀態(tài)及自定義分享內(nèi)容接口(即將廢棄):

wx.onMenuShareTimeline({
  title: '', // 分享標(biāo)題
  link: '', // 分享鏈接解虱,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號JS安全域名一致
  imgUrl: '', // 分享圖標(biāo)
  success: function () {
  // 用戶點擊了分享后執(zhí)行的回調(diào)函數(shù)
  }
},

獲取“分享到QQ”按鈕點擊狀態(tài)及自定義分享內(nèi)容接口(即將廢棄):

wx.onMenuShareQQ({
  title: '', // 分享標(biāo)題
  desc: '', // 分享描述
  link: '', // 分享鏈接
  imgUrl: '', // 分享圖標(biāo)
  success: function () {
  // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
  },
  cancel: function () {
  // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
  }
});

\color{ red}{ 注意: }

如果用舊版的 wx.onMenuShareTimeline攘须、wx.onMenuShareAppMessage、wx.onMenuShareQQ 接口饭寺,請用1.4.0或者1.0.0的SDK阻课。

我們用新接口的時候一直提示沒有權(quán)限,用原接口的時候提示簽名錯誤艰匙,后來換了1.0.0的SDK,后臺又重新檢查了下簽名抹恳,并把 jsapi_ticket 緩存去掉员凝。主要就是要一步步去測試,然后就神奇的好了奋献。

完整的自定義分享代碼:

getWXShare() {
          axios.get('***/***/getShareTicket', MD5({
            url: location.href
          }), function (data) {
            if (data.code === 200) {
              wx.config({
                // debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來健霹,若要查看傳入的參數(shù),可以在pc端打開瓶蚂,參數(shù)信息會通過log打出糖埋,僅在pc端時才會打印。
                appId: data.data.appId, //后臺 必填窃这,公眾號的唯一標(biāo)識
                timestamp: data.data.timestamp, // 必填瞳别,后臺生成簽名的時間戳
                nonceStr: data.data.nonceStr, // 必填,后臺生成簽名的隨機串
                signature: data.data.signature,// 必填杭攻,后臺簽名
                jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareAppMessage','onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareQZone']
              });

              wx.ready(function () {
                //分享到朋友圈(舊)
                wx.onMenuShareTimeline({
                  title: '要分享的標(biāo)題', // 分享標(biāo)題
                  desc: '要分享的簡介',
                  link: "要分享的地址", // 分享鏈接祟敛,
                  imgUrl: '要分享圖標(biāo)', // 分享圖標(biāo)
                  success: function () {
                    // 用戶點擊了分享后執(zhí)行的回調(diào)函數(shù)
                    // console.log("分享成功");
                  },
                  cancel: function () {
                    // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
                    // console.log("分享取消");
                  }
                });
                // 朋友(舊)
                wx.onMenuShareAppMessage({
                  title: '要分享的標(biāo)題', // 分享標(biāo)題
                  desc: '要分享的簡介',
                  link: "要分享的地址", // 分享鏈接,
                  imgUrl: '要分享圖標(biāo)', // 分享圖標(biāo)
                  success: function () {
                    // 用戶點擊了分享后執(zhí)行的回調(diào)函數(shù)
                    // console.log("分享成功2");
                  },
                  cancel: function () {
                    // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
                    // console.log("分享取消2");
                  }
                });
              });
              //必須放wx.ready后面 否則無法執(zhí)行
              wx.error(function(res){
                //config信息驗證失敗會執(zhí)行error函數(shù)兆解,如簽名過期導(dǎo)致驗證失敗馆铁,具體錯誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看锅睛,對于SPA可以在這里更新簽名埠巨。
              });
            } else {
              alert('請稍后后再試')
            }
          })
},
總結(jié):

到這一步分享的操作基本就完成了历谍,建議在測試時將debug打開,看看分享提示辣垒,從而判定是否分享成功望侈。如果不成功,可以參考一下在開發(fā)時候遇到的坑乍构。

出現(xiàn) nvalid url domain 提示
1)檢查當(dāng)前頁面所在域名與使用的appid沒有綁定甜无,請確認(rèn)正確填寫綁定的域名,僅支持80(http)和443(https)兩個端口哥遮,因此不需要填寫端口號岂丘。
出現(xiàn)invalid signature簽名錯誤提示
1)檢查生成signature是否正確,可以通過簽名校驗工具來判定后端傳過來的nonceStr眠饮、timestamp與請求后端接口傳的地址奥帘,與最后簽名是否一致。

  1. config時仪召,nonceStr 記得駝峰寫法寨蹋。
  2. 簽名用的url必須是調(diào)用JS接口頁面的完整URL,即當(dāng)前頁面的完整URL扔茅。
    提示是成功的已旧,但是分享出來圖標(biāo)不見或者desc不顯示的情況
    1. 分享的地址不要帶端口號。
      2)分享desc 不要帶有敏感詞匯召娜。
新更新:(2021.12.20)

最近微信新修改了自定義分享規(guī)則运褪,通過鏈接點進(jìn)來的分享只能分享鏈接;通過分享和掃碼進(jìn)來的可以分享鏈接+標(biāo)題+縮略圖玖瘸。(實測)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末秸讹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子雅倒,更是在濱河造成了極大的恐慌璃诀,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔑匣,死亡現(xiàn)場離奇詭異劣欢,居然都是意外死亡,警方通過查閱死者的電腦和手機殖演,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門氧秘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人趴久,你說我怎么就攤上這事丸相。” “怎么了彼棍?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵灭忠,是天一觀的道長膳算。 經(jīng)常有香客問我,道長弛作,這世上最難降的妖魔是什么涕蜂? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮映琳,結(jié)果婚禮上机隙,老公的妹妹穿的比我還像新娘。我一直安慰自己萨西,他們只是感情好有鹿,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谎脯,像睡著了一般葱跋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上源梭,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天娱俺,我揣著相機與錄音,去河邊找鬼废麻。 笑死荠卷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烛愧。 我是一名探鬼主播僵朗,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼屑彻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顶吮,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤社牲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后悴了,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搏恤,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年湃交,在試婚紗的時候發(fā)現(xiàn)自己被綠了熟空。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肢专。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡樱报,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锥累,到底是詐尸還是另有隱情才沧,我是刑警寧澤迈喉,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布绍刮,位于F島的核電站,受9級特大地震影響挨摸,放射性物質(zhì)發(fā)生泄漏孩革。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一得运、第九天 我趴在偏房一處隱蔽的房頂上張望膝蜈。 院中可真熱鬧,春花似錦熔掺、人聲如沸饱搏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窍帝。三九已至,卻和暖如春诽偷,著一層夾襖步出監(jiān)牢的瞬間坤学,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工报慕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留深浮,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓眠冈,卻偏偏與公主長得像飞苇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蜗顽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容