最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

微信網(wǎng)頁登錄邏輯與實現(xiàn)方法

 更新時間:2019年04月29日 14:26:22   作者:yuanxin  
這篇文章主要介紹了微信網(wǎng)頁登錄邏輯與實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

現(xiàn)在的網(wǎng)站開發(fā),都繞不開微信登錄(畢竟微信已經(jīng)成為國民工具)。雖然文檔已經(jīng)寫得很詳細,但是對于沒有經(jīng)驗的開發(fā)者還是容易踩坑。

所以,專門記錄一下微信網(wǎng)頁認證的交互邏輯,也方便自己日后回查:

  1. 加載微信網(wǎng)頁sdk
  2. 繪制登陸二維碼:新tab頁面繪制 / 本頁面iframe繪制
  3. 用戶掃碼登陸,前端跳入回調(diào)網(wǎng)址
  4. 回調(diào)網(wǎng)址進一步做邏輯處理,如果是頁內(nèi)iframe繪制二維碼,需要通知頂級頁

微信網(wǎng)頁SDK加載

在多人團隊協(xié)作中,加載資源的代碼需要格外小心。因為可能會有多個開發(fā)者在同一業(yè)務邏輯下調(diào)用,這會造成資源的重復加載。

處理方法有兩種,第一種是對外暴露多余接口,專門check是否重復加載。但是考慮到調(diào)用者每次在加載前,都需要顯式調(diào)用check()方法進行檢查,難免會有遺漏。

所以采用第二種方法--設計模式中的緩存模式,代碼如下:

// 備忘錄模式: 防止重復加載
export const loadWeChatJs = (() => {
 let exists = false; // 打點
 const src = '//res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'; // 微信sdk網(wǎng)址

 return () => new Promise((resolve, reject) => {
  // 防止重復加載
  if(exists) return resolve(window.WxLogin);
  
  let script = document.createElement('script');
  script.src = src;
  script.type = 'text/javascript';
  script.onerror = reject; // TODO: 失敗時候, 可以移除script標簽
  script.onload = () => {
   exists = true;
   resolve(window.WxLogin);
  };
  document.body.appendChild(script);
 });
})();

繪制登陸二維碼

根據(jù)《微信登陸開發(fā)指南》,將參數(shù)傳遞給window.WxLogin()即可。

// 微信默認配置
const baseOption = {
 self_redirect: true, // true: 頁內(nèi)iframe跳轉(zhuǎn); false: 新標簽頁打開 
 id: 'wechat-container', 
 appid: 'wechat-appid',
 scope: 'snsapi_login',
 redirect_uri: encodeURIComponent('//1.1.1.1/'),
 state: '',
};

export const loadQRCode = (option, intl = false, width, height) => {
 const _option = {...baseOption, ...option};

 return new Promise((resolve, reject) => {
  try {
   window.WxLogin(_option);
   const ele = document.getElementById(_option['id']);
   const iframe = ele.querySelector('iframe');
   iframe.width = width? width : '300';
   iframe.height = height? height : '420'; 
   // 處理國際化
   intl && (iframe.src = iframe.src + '&lang=en');
   resolve(true);
  } catch(error) {
   reject(error);
  }
 });
};

在需要使用的業(yè)務組件中,可以在周期函數(shù)componentDidMount調(diào)用,下面是demo代碼:

componentDidMount() {
  const wxOption = {
    // ...
  };
  loadWeChatJs()
    .then(WxLogin => loadQRCode(wxOption))
    .catch(error => console.log(`Error: ${error.message}`));  
}

回調(diào)網(wǎng)址與iframe通信

這一塊我覺得是微信登陸交互中最復雜和難以理解的一段邏輯。開頭有講過,微信二維碼渲染有2中方式,一種是打開新的標簽頁,另一種是在指定id的容器中插入iframe。

毫無疑問,第二種交互方式更友好,因為要涉及不同級層的頁面通信,代碼處理也更具挑戰(zhàn)。

為了方便說明,請先看模擬的數(shù)據(jù)配置:

// redirect 地址會被后端拿到, 后端重定向到此地址, 前端會訪問此頁面
// redirect 地址中的參數(shù), 是前端人員留給自己使用的; 后端會根據(jù)業(yè)務需要, 添加更多的字段, 然后一起返回前端
const querystr = '?' + stringify({
 redirect: encodeURIComponent(`${window.location.origin}/account/redirect?` + stringify({
  to: encodeURIComponent(window.location.origin),
  origin: encodeURIComponent(window.location.origin),
  state: 'login'
 })),
 type: 'login'
});

const wxOption = {
 id: 'wechat-container',
 self_redirect: true,
 redirect_uri: encodeURIComponent(`//1.1.1.1/api/socials/weixin/authorizations${querystr}`) // 微信回調(diào)請求地址
};

前后端、微信服務器、用戶端交互邏輯

按照上面的配置,我描述一下前端、用戶端、微信服務器和后端交互的邏輯:

  • 前端根據(jù)wxOption加載了二維碼,所有信息都放在了二維碼中。同時監(jiān)聽微信服務器的消息。
  • 用戶手機掃碼,通知微信服務器確定登陸。
  • 微信服務器接受到用戶的掃碼請求,轉(zhuǎn)發(fā)給前端。
  • 前端收到微信服務器傳來消息,根據(jù)wxOption的redirect_uri參數(shù),跳轉(zhuǎn)到此url地址。注意:
    • 這個接口地址是后端的,請求方式是GET
    • 前端通過拼接params攜帶參數(shù)
    • 地址會被拼接微信服務器傳來的一個臨時token,用于交給后端換取用戶公眾密鑰
  • 后端接收到/api/socials/weixin/authorizations${querystr}的請求,decode解碼querystr中的信息。然后向微信服務端請求用戶公眾密鑰。根絕前后端的約定(demo中用的是redirect字段),重定向到前端指定的redirect字段,并且拼接用戶公眾密鑰等更多信息。
  • 前端知悉重定向,跳到重定向的路由(demo中用的是/account/redirect)
  • 在對應的路由處理后端傳來的用戶密鑰等數(shù)據(jù)即可
  • 至此,微信認證的四端交互邏輯完成

跨Iframe通信

前面流程走完了,現(xiàn)在的情況是頁面中iframe的二維碼區(qū)域,已經(jīng)被替換成了/account/redirect?...的內(nèi)容。

為了實現(xiàn)通信,需要在頁面的周期中監(jiān)聽message事件,并在組件卸載時,卸載此事件:

componentDidMount() {
 // ... ...
 
 window.addEventListener('message', this.msgReceive, false);
}

componentWillUnmount() {
 window.removeEventListener('message', this.msgReceive);
}

msgReceive(event) {
 // 監(jiān)測是否是安全iframe
 if(!event.isTrusted) {
  return;
 }
 console.log(event.data); // 獲取iframe中傳來的數(shù)據(jù), 進一步進行邏輯處理
}

而在/account/redirect?...路由對應的組件中,我們需要解析路由中的params參數(shù),按照業(yè)務邏輯檢查后,將結果傳遞給前面的頁面:

componentDidMount() {
  // step1: 獲取url中params參數(shù)
  const querys = getQueryVariable(this.props.location.search);
  // step2: 檢查querys中的數(shù)據(jù)是否符合要求 ... 
  // step3: 向頂級頁面?zhèn)鬟f消息
  return window.parent && window.parent.postMessage('data', '*');
}

至此,微信網(wǎng)頁認證的流程完成。

更多:關于iframe通信的更多細節(jié),請查看MDN的文檔

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • JavaScript canvas實現(xiàn)雨滴特效

    JavaScript canvas實現(xiàn)雨滴特效

    這篇文章主要為大家詳細介紹了JavaScript canvas實現(xiàn)雨滴特效,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • layer.prompt使文本框為空的情況下也能點擊確定的方法

    layer.prompt使文本框為空的情況下也能點擊確定的方法

    今天小編就為大家分享一篇layer.prompt使文本框為空的情況下也能點擊確定的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • Javascript異步編程async實現(xiàn)過程詳解

    Javascript異步編程async實現(xiàn)過程詳解

    這篇文章主要介紹了Javascript異步編程async實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • 解決JavaScript中0.1+0.2不等于0.3問題

    解決JavaScript中0.1+0.2不等于0.3問題

    這篇文章主要介紹了解決JavaScript中0.1+0.2不等于0.3問題,需要的朋友可以參考下
    2018-10-10
  • Js圖片點擊切換輪播實現(xiàn)代碼

    Js圖片點擊切換輪播實現(xiàn)代碼

    這篇文章主要介紹了Js圖片點擊切換輪播實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • setTimeout與setInterval的區(qū)別淺析

    setTimeout與setInterval的區(qū)別淺析

    這篇文章主要給大家介紹了關于setTimeout與setInterval區(qū)別的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用js具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-03-03
  • js?實現(xiàn)div拖拽拉伸完整示例

    js?實現(xiàn)div拖拽拉伸完整示例

    這篇文章主要為大家介紹了js?實現(xiàn)div拖拽拉伸完整示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • JS基于遞歸實現(xiàn)網(wǎng)頁版計算器的方法分析

    JS基于遞歸實現(xiàn)網(wǎng)頁版計算器的方法分析

    這篇文章主要介紹了JS基于遞歸實現(xiàn)網(wǎng)頁版計算器的方法,結合實例形式分析了javascript采用遞歸算法實現(xiàn)網(wǎng)頁版計算器的步驟與相關操作技巧,需要的朋友可以參考下
    2017-12-12
  • 使用TypeScript實現(xiàn)高效的異步隊列任務管理

    使用TypeScript實現(xiàn)高效的異步隊列任務管理

    在javaScript項目開發(fā)中,異步編程是不可或缺的一部分,從網(wǎng)絡請求到延時操作,異步操作使得我們能夠在等待某個任務完成時繼續(xù)執(zhí)行其他任務,提高應用的響應性和性能,本文使用JavaScript實現(xiàn)一個異步隊列來優(yōu)雅地管理復雜的異步任務流,需要的朋友可以參考下
    2024-03-03
  • js CSS操作方法集合

    js CSS操作方法集合

    用js實現(xiàn)的對css的一些操作方法,集合,方便需要用js控制css的朋友
    2008-10-10

最新評論

应城市| 洪雅县| 沁水县| 沅陵县| 玉屏| 五寨县| 江源县| 阜宁县| 咸丰县| 杭锦后旗| 安徽省| 内黄县| 盐亭县| 安康市| 三原县| 时尚| 灵石县| 昌平区| 承德县| 桐梓县| 项城市| 修武县| 滦平县| 班玛县| 什邡市| 怀宁县| 卢龙县| 剑河县| 林口县| 安西县| 田东县| 库伦旗| 揭东县| 龙井市| 边坝县| 洱源县| 晋中市| 玉山县| 祁连县| 连云港市| 梁河县|