摘要:頁(yè)面用瀏覽器自帶返回和安卓物理返回死循環(huán)的話,直接看高潮部分背景折磨我兩個(gè)工作日加周末一天的問(wèn)題,我覺(jué)得還是有必要記錄一下,為什么程序員總是加班,就是遇到這些意想不到的問(wèn)題需求領(lǐng)導(dǎo)我想做兩個(gè)頁(yè)面,放在微信里面可以訪問(wèn)我簡(jiǎn)單啊,用實(shí)現(xiàn)產(chǎn)品設(shè)計(jì)
頁(yè)面用瀏覽器自帶返回和安卓物理返回死循環(huán)的話,直接看高潮部分
背景折磨我兩個(gè)工作日加周末一天的問(wèn)題,我覺(jué)得還是有必要記錄一下,為什么程序員總是加班,就是遇到這些意想不到的問(wèn)題
需求領(lǐng)導(dǎo):我想做兩個(gè)頁(yè)面,放在微信里面可以訪問(wèn)
我:簡(jiǎn)單啊,用H5實(shí)現(xiàn)
產(chǎn)品設(shè)計(jì)中...
產(chǎn)品:好了,看看沒(méi)問(wèn)題就開(kāi)始開(kāi)發(fā)吧
我:什么時(shí)候多了一個(gè)需要獲取用戶信息(產(chǎn)品總是給人驚喜不端)
沒(méi)有試過(guò)微信授權(quán)這一塊,首先內(nèi)心三連問(wèn),能不能拒絕,能不能改需求,能不能通過(guò)熟悉的秘方實(shí)現(xiàn);然而并沒(méi)有什么用(笑哭表情)
開(kāi)發(fā)中業(yè)務(wù)功能沒(méi)什么難點(diǎn),模擬一個(gè)用戶信息,很快就開(kāi)發(fā)完成了...
微信網(wǎng)頁(yè)授權(quán)官方文檔:https://mp.weixin.qq.com/wiki...
1.登錄自己的服務(wù)號(hào)?,查看已有的權(quán)限
注意:這里只能是服務(wù)號(hào),訂閱號(hào)沒(méi)有權(quán)限,服務(wù)號(hào)只能由企業(yè)和組織申請(qǐng)
2.公眾號(hào)設(shè)置
注意:授權(quán)回調(diào)域名配置規(guī)范為全域名,比如需要網(wǎng)頁(yè)授權(quán)的域名為:www.qq.com,配置以后此域名下面的頁(yè)面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以進(jìn)行OAuth2.0鑒權(quán)。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com無(wú)法進(jìn)行OAuth2.0...
注意:下載這個(gè)文件放在域名對(duì)應(yīng)的根目錄下
3.鏈接的生成
https://open.weixin.qq.com/co...
以訪問(wèn)www.qq.com/#/detail.html為例,上面第2步的網(wǎng)頁(yè)授權(quán)域名設(shè)置成 www.qq.com
REDIRECT_URI為encodeURIComponent("http://www.qq.com/#/detail.html")
SCOPE為snsapi_base或snsapi_userinfo,區(qū)別是只獲取用戶id,還是獲取更多用戶信息
state隨便寫(xiě)吧,以123為例(沒(méi)有看出具體有什么用)
其它參數(shù)不變
注意:為什么要用encodeURIComponent,你想想,你在url里面直接寫(xiě)url,怎么能直接把它解析成參數(shù)
4.放在微信里訪問(wèn)
把第3步上面生成的鏈接,做為聊天消息,拷貝到微信里面,點(diǎn)擊打開(kāi),此時(shí)我們用alert(location.href)就會(huì)發(fā)現(xiàn),地址變成了http://www.qq.com/?code=生成...
// 獲取url參數(shù) export function getQueryVariable(variable) { const query = window.location.search.substring(1) const vars = query.split("&") for (let i=0; i注意:code只能用一次,而且還有時(shí)間限制,code插入的位置尤其要注意,不是在
/#/后面,所以用vue或react的路由組件中獲取路由參數(shù)方式是不可行的,老老實(shí)實(shí)的寫(xiě)原生js獲取5.通過(guò)code獲取用戶id
code獲取到了以后前端就無(wú)能為力了,接下來(lái)的步驟只能交給后臺(tái)了(數(shù)據(jù)安全性考慮,比如AppSecret不能暴露給前端),自古以來(lái),前端的地位略低于后端,nodejs的出現(xiàn)極大的拯救了前端,雖然后面的事情前端做不了,但我們可以用nodejs或者是類(lèi)似于postman這種的工具,把后面的接口模擬跑通,然后直接告訴后端,你該調(diào)什么接口,用什么參數(shù),后端文檔都不用看;當(dāng)然你也可以做個(gè)小白紙,什么都拋給后端,讓后端指揮你怎么做(在一個(gè)團(tuán)隊(duì)中,各個(gè)角色的重要性,就看能做的事情)
網(wǎng)頁(yè)授權(quán)就這么搞完了,是不是很簡(jiǎn)單(笑哭表情),可以愉快的玩耍了
當(dāng)我把這個(gè)鏈接通過(guò)微信右上角分享給同事一起測(cè)試時(shí),啪啪打臉了...,呈現(xiàn)的現(xiàn)象
1.通過(guò)code獲取用戶id,報(bào)錯(cuò)了
2.分享標(biāo)題,描述,圖標(biāo)好丑,我能不能改(好像沒(méi)有分享這個(gè)需求,但不分享的話,用戶怎么看,我要不要做,沒(méi)有這個(gè)需求,我要不要把鍋丟給產(chǎn)品,我好方,但僅有的一點(diǎn)點(diǎn)職業(yè)素養(yǎng)告訴我,我還是做吧,做為一個(gè)合格的程序員,必備的技能不就是腦補(bǔ)一些產(chǎn)品沒(méi)想到需求嗎(笑哭表情))分析原因:
1.打印出分享的地址alert(location.href),為http://www.qq.com/?code=上一...,微信分享出去的是當(dāng)前訪問(wèn)的地址(原滋原味,加了一些防腐劑,多了一個(gè)from=xxxx,應(yīng)該是來(lái)源),但我理想中想要的是上面第3中的地址(重定向之前的地址),報(bào)錯(cuò)的原因是同一個(gè)code用了兩次
解決思路:
微信網(wǎng)頁(yè)分享
1.自定義分享地址,此時(shí)的思路是,地址改成https://open.weixin.qq.com/co... 這種
2.自定義標(biāo)題,描述和圖片
3.最終方案看下面官方文檔:https://mp.weixin.qq.com/wiki...
1.還是先配置相應(yīng)的權(quán)限
2.生成簽名(后端做的,前端可以選擇跳過(guò))
這個(gè)時(shí)候就不得不吐槽微信的文檔了,殘缺了,在第一步就卡住了,只能求助網(wǎng)友,后面我發(fā)現(xiàn)
這里有,IP白名單也要設(shè)置,否則是拿不到access_token的,其它的簽名怎么生成的后端照著文檔做就行了
注意點(diǎn):網(wǎng)頁(yè)授權(quán)和分享是兩個(gè)完全獨(dú)立的模塊,分享的access_token和授權(quán)返回的access_token是完全不一樣的概念
3.前端配置
yarn add weixin-js-sdk
此時(shí)我的版本是"weixin-js-sdk": "^1.4.0-test", 微信客戶端的版本是7.0.4,竟然遇到一個(gè)大坑
微信官方讓我用最新的接口,我試了很久都沒(méi)有調(diào)通,總以為是自己的姿勢(shì)不對(duì),后面實(shí)在不行了,我試了一下老接口,竟然通了,竟然通了,竟然通了,我想崩潰了
上代碼
wx.config({ debug: false, // 開(kāi)啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來(lái),在pc端時(shí)會(huì)打印出來(lái),不需要的話可以將true改成false。 appId: data.appid, // 必填,公眾號(hào)的唯一標(biāo)識(shí) timestamp: data.timestamp, // 必填,生成簽名的時(shí)間戳 nonceStr: data.nonceStr, // 必填,生成簽名的隨機(jī)串 signature: data.signature, // 必填,簽名 jsApiList: ["onMenuShareAppMessage","onMenuShareTimeline","onMenuShareQQ","onMenuShareQZone"] }) wx.ready(function () { //分享到朋友圈 wx.onMenuShareTimeline({ title, // 分享標(biāo)題 link, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致 imgUrl, // 分享圖標(biāo) }) //分享給朋友 wx.onMenuShareAppMessage({ title, // 分享標(biāo)題 desc, // 分享描述 link, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致 imgUrl, // 分享圖標(biāo) }) //分享到QQ wx.onMenuShareQQ({ title, // 分享標(biāo)題 desc, // 分享描述 link, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致 imgUrl, // 分享圖標(biāo) }) //分享到QQ空間 wx.onMenuShareQZone({ title, // 分享標(biāo)題 desc, // 分享描述 link, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致 imgUrl, // 分享圖標(biāo) }) })注意:
1.data是后臺(tái)返回的簽名信息
2.分享鏈接,該鏈接域名必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致,公眾號(hào)里面配置的是www.qq.com,這里分享的地址只能是以www.qq.com開(kāi)頭的,和我們理想的https://open.weixin.qq.com/co... 開(kāi)頭差距很大(怎么授權(quán),好方)如果只是單純的自定義分享,到這里就結(jié)束了,如果既要分享又要授權(quán),又有問(wèn)題需要解決了
4.重定向
初始打開(kāi)地址為:http://www.qq.com/#/detail.html,這個(gè)時(shí)候不帶code
進(jìn)入頁(yè)面之后。location. (下面都稱(chēng)為重定向)
頁(yè)面地址變成了http://www.qq.com/?code=生成...
用的是同一個(gè)頁(yè)面,所以需要判斷url有沒(méi)有code,來(lái)決定是否要執(zhí)行第2步,否則會(huì)死循環(huán)
文章寫(xiě)到這里,已經(jīng)解決了授權(quán)+分享,是不是感覺(jué)故事很平穩(wěn),一部好的電影怎么能這么快結(jié)束
高潮(大坑來(lái)了)現(xiàn)象
微信中打開(kāi)頁(yè)面,用安卓的物理返回鍵,點(diǎn)一下返回不了,需要連續(xù)快速點(diǎn)兩下才能退出
分析原因
打開(kāi)的頁(yè)面是不帶code的地址,經(jīng)過(guò)重定向后,生成了帶code的地址,此時(shí)瀏覽器的歷史記錄中會(huì)有兩條記錄,從帶code的地址返回到不帶code的地址,頁(yè)面判斷沒(méi)有帶code,又會(huì)重定向到帶code的頁(yè)面,產(chǎn)生了死循環(huán)
解決方案1.不讓它產(chǎn)生多一條的記錄
首先想到的是location.replace(url), 發(fā)現(xiàn)把url替換成授權(quán)的地址時(shí)(https://open.weixin.qq.com/co...),并不會(huì)像想象中的那樣工作,還是會(huì)有兩條歷史記錄(不清楚微信為什么不解決,還是解決不了)
結(jié)果:失敗
2.代碼控制清除一條歷史記錄
const params = getQueryParams() const code = sessionStorage.getItem("code") if (!params.code && !code) { let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${yourAppId}&redirect_uri=${encodeURIComponent(location.href)}&response_type=code&scope=snsapi_base&state=1#wechat_redirect` window.location.replace(url) } else if(!code){ sessionStorage.setItem("code", params.code) history.back() }搜索了一大圈,看見(jiàn)了這段代碼(來(lái)自:https://www.cnblogs.com/wonyu...),仿佛看見(jiàn)了光,里面比較講究的就是
sessionStorage(只在當(dāng)前會(huì)話有效),用當(dāng)前會(huì)話窗口儲(chǔ)存的code,來(lái)判斷不帶code的頁(yè)面要不要重定向看似很完美的代碼,還是逃不過(guò)微信的大坑,通過(guò)鏈接進(jìn)入時(shí),偶爾會(huì)遇到頁(yè)面空白
原因:
上面用到的歷史記錄返回,頁(yè)面不刷新(偶爾),我嘗試過(guò)強(qiáng)制微信瀏覽器刷新,甚至懷疑是vue的坑,然后用原生寫(xiě)了一段js來(lái)操作dom,并沒(méi)有什么用
最后發(fā)現(xiàn)返回的時(shí)候,js都能正常的執(zhí)行,UI不重新渲染,UI不重新渲染,UI不重新渲染,偶爾出現(xiàn),不是必現(xiàn),我再次好方
結(jié)果:偶爾失敗
3.返回兩次,才能退出
借鑒上面的思路,判斷當(dāng)前會(huì)話窗口儲(chǔ)存的code是否有值,有值就不重定向
結(jié)果:解決了偶爾不渲染的問(wèn)題和死循環(huán)的問(wèn)題,但對(duì)于有輕微強(qiáng)迫癥的我來(lái)說(shuō),需要點(diǎn)兩次才能返回還是挺難接受的
本來(lái)屬于愉快的周末,就在微信這個(gè)大坑里結(jié)束了,關(guān)上電腦,沉思一會(huì)(想想如何說(shuō)服測(cè)試同學(xué)這個(gè)問(wèn)題解決不了,是微信的坑(笑哭表情))
結(jié)尾處女座最大的悲哀就是心里不能放事情,總感覺(jué)不踏實(shí),休息也休息不好(悲哀)
突然想到前段時(shí)間開(kāi)發(fā)的app,自己控制過(guò)android的返回,微信會(huì)不會(huì)也提供了自定義返回呢,經(jīng)過(guò)一大堆的搜索,發(fā)現(xiàn)js就有能監(jiān)聽(tīng)瀏覽器返回的事件(有些知識(shí)點(diǎn)不用,慢慢就忘了),兜兜轉(zhuǎn)轉(zhuǎn)了一大圈,至少用我的周末幫大家證明了網(wǎng)上說(shuō)的很多方式行不通,哈哈哈,終極解決,上代碼(vue的思路)
created () { // 當(dāng)前需要直接退出的頁(yè)面 window.history.pushState("_android_back", null, location.href) window.addEventListener("popstate", this.popstate, false) }, destroyed: function () { // 記得清除,不然單頁(yè)面,其它頁(yè)面也可以用 window.removeEventListener("popstate", this.popstate, false) }, methods: { popstate () { wx.closeWindow() // 微信網(wǎng)頁(yè)退出 } }注意:為什么要多window.history.pushState(null, null, "")這句代碼,因?yàn)閜opstate只能監(jiān)聽(tīng)pushState創(chuàng)建的
備注:微信的文檔會(huì)更新,當(dāng)你使用時(shí)(看一下這篇文章的出生時(shí)間),最好參考官方文檔,如果你覺(jué)得有一點(diǎn)幫助了你,請(qǐng)點(diǎn)個(gè)贊(程序員寫(xiě)文章不容易,最煩寫(xiě)這種隨時(shí)可能過(guò)時(shí)的文章,哈哈哈)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/104001.html
摘要:所以,把本人踩過(guò)的一些坑在這里分享出來(lái),讓準(zhǔn)備搭建風(fēng)控的人心里有個(gè)數(shù)。結(jié)語(yǔ)信息采集往往是實(shí)施風(fēng)控的最難的一個(gè)環(huán)節(jié),但也是最重要的環(huán)節(jié),覆蓋質(zhì)量時(shí)效都決定了項(xiàng)目的成敗。 showImg(https://segmentfault.com/img/bVEcg5?w=900&h=658); 作者前言 從業(yè)近10年,大大小小參與了3家公司不同領(lǐng)域的風(fēng)控系統(tǒng)的設(shè)計(jì),從前到后把風(fēng)控系統(tǒng)所有環(huán)節(jié)都細(xì)細(xì)...
摘要:所以,把本人踩過(guò)的一些坑在這里分享出來(lái),讓準(zhǔn)備搭建風(fēng)控的人心里有個(gè)數(shù)。結(jié)語(yǔ)信息采集往往是實(shí)施風(fēng)控的最難的一個(gè)環(huán)節(jié),但也是最重要的環(huán)節(jié),覆蓋質(zhì)量時(shí)效都決定了項(xiàng)目的成敗。 showImg(/img/bVEcg5?w=900&h=658); 作者前言 從業(yè)近10年,大大小小參與了3家公司不同領(lǐng)域的風(fēng)控系統(tǒng)的設(shè)計(jì),從前到后把風(fēng)控系統(tǒng)所有環(huán)節(jié)都細(xì)細(xì)的琢磨過(guò),然而至今仍然感覺(jué)剛剛一只腳踏進(jìn)門(mén)而已。...
摘要:所以,把本人踩過(guò)的一些坑在這里分享出來(lái),讓準(zhǔn)備搭建風(fēng)控的人心里有個(gè)數(shù)。結(jié)語(yǔ)信息采集往往是實(shí)施風(fēng)控的最難的一個(gè)環(huán)節(jié),但也是最重要的環(huán)節(jié),覆蓋質(zhì)量時(shí)效都決定了項(xiàng)目的成敗。 showImg(https://segmentfault.com/img/bVEcg5?w=900&h=658); 作者前言 從業(yè)近10年,大大小小參與了3家公司不同領(lǐng)域的風(fēng)控系統(tǒng)的設(shè)計(jì),從前到后把風(fēng)控系統(tǒng)所有環(huán)節(jié)都細(xì)細(xì)...
閱讀 653·2021-11-18 13:12
閱讀 1394·2021-11-15 11:39
閱讀 2543·2021-09-23 11:22
閱讀 6294·2021-09-22 15:15
閱讀 3727·2021-09-02 09:54
閱讀 2377·2019-08-30 11:10
閱讀 3311·2019-08-29 14:13
閱讀 2965·2019-08-29 12:49