剛開始接到這個(gè)項(xiàng)目時(shí),因?yàn)閷?duì)Angular比較熟悉,所以就選用了Angular6+Ionic4框架構(gòu)造整個(gè)項(xiàng)目,開發(fā)界面時(shí)一切順利,到了開發(fā)微信JS-SDK的時(shí)候就有點(diǎn)懵了,網(wǎng)上關(guān)于Angular2~6開發(fā)微信JS-SDK的案例一個(gè)都找不到,這下就不好辦了,這時(shí)候再換框架的話就太拖進(jìn)度了,會(huì)被罵死,而且新框架也不一定那么適用。
辛辛苦苦配置好服務(wù)器之后,開始開發(fā)JS-SDK了,從官方平臺(tái)上下載了demo源碼,有Java、node、PHP、pyhon四個(gè)版本的代碼,我對(duì)PHP比較熟悉,所以直接拿PHP代碼開干。代碼分為四個(gè)文件

首先,access_token.php 和 jsapi_ticket.php 兩個(gè)文件是用來緩存全局變量access_token,jsapi_ticket和expire_time的。


然后就是jssdk.php,是主要的文件,里面存放的是請(qǐng)求方法,通過調(diào)用此處的方法,請(qǐng)求微信JS-SDK的配置信息。
sample.php文件是入口文件,用php語言寫的一個(gè)html頁面,令人尷尬的是,這個(gè)頁面是直接調(diào)用jssdk.php中的方法請(qǐng)求JS-SDK的配置信息,直接使用的,這種前后端不分離的做法,不存在任何的問題。可是當(dāng)我在開發(fā)angular項(xiàng)目的時(shí)候,需要前后端分離,那么就要通過http請(qǐng)求一個(gè)php文件,然后在這個(gè)php文件中調(diào)用jssdk.php的方法請(qǐng)求到參數(shù),然后再返回給前端,最后前端獲取到配置信息,直接使用。下面是我寫的php代碼:

從流程上來講這樣是沒問題的,之前的JS安全域名和IP地址白名單都已經(jīng)配好了的,運(yùn)行demo代碼的時(shí)候也成功獲取到配置信息。但是,當(dāng)我把項(xiàng)目打包好部署到服務(wù)器之后,發(fā)現(xiàn)第一個(gè)問題:在angular項(xiàng)目中如何注入配置信息?首先,angular組件中肯定是沒wx這個(gè)對(duì)象的,需要導(dǎo)入微信JS-SDK的js文件:http://res.wx.qq.com/open/js/jweixin-1.4.0.js
一開始,我是在項(xiàng)目的配置文件中導(dǎo)入,但是發(fā)現(xiàn)并沒有用,在應(yīng)用模塊中導(dǎo)入不了wx對(duì)象,而且在渲染出來的頁面中并沒有加載到jweixin-1.4.0.js?。

然后我又試著直接在index文件的頭部信息中引入:

這樣引用之后,在渲染出來的頁面中看到有加載到jweixin-1.4.0.js。

但是這時(shí)候出現(xiàn)了困擾我的一個(gè)問題,那就是如何獲取js文件中的wx對(duì)象。angular框架引入第三方框架的時(shí)候,是通過導(dǎo)入的方法獲取到對(duì)象的,可是現(xiàn)在沒辦法這樣做,那么我要如何獲取到這個(gè)wx對(duì)象呢?
在網(wǎng)上找了很久,沒發(fā)現(xiàn)有Angular6開發(fā)微信的案例,很多都是掛羊頭賣狗肉(我一直認(rèn)為,Angular2~6和Angular1.X不是同一個(gè)框架,兩者區(qū)別太大)。網(wǎng)上找不到答案后,就只能自己想辦法。后面突然想起之前做混合開發(fā)的時(shí)候,通過window注入對(duì)象由android和IOS調(diào)用的例子,我試著打印window對(duì)象,發(fā)現(xiàn)在加載了jweixin-1.4.0.js之后,wx對(duì)象下面掛載了一個(gè)wx對(duì)象,于是我想到可以通過window獲取wx對(duì)象:

嗯? 這樣是可以的,所以說,在加載了JS-SDK接口文件之后,不需要注入,直接從window下獲取wx對(duì)象。
本來到了這里,應(yīng)該就可以請(qǐng)求到配置信息了,事實(shí)上配置信息確實(shí)請(qǐng)求到了,但是在調(diào)用驗(yàn)證接口的時(shí)候提示簽名錯(cuò)誤。


這我就納悶了,明明配置信息都請(qǐng)求到了,使用的時(shí)候又提示錯(cuò)誤。我想了好久,都不知道什么原因。百度到出現(xiàn)這種錯(cuò)誤的幾種原因:
1.確認(rèn)簽名算法正確,可用?http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign?頁面工具進(jìn)行校驗(yàn)。
2.確認(rèn)config中noncestr, timestamp與用以簽名中的對(duì)應(yīng)noncestr, timestamp一致。
3.確認(rèn)url是頁面完整的url,包括GET參數(shù)部分。
4.確認(rèn) config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
5.確保一定緩存access_token和jsapi_ticket,可以減少兩次服務(wù)器請(qǐng)求加速體驗(yàn)外,還避免了觸發(fā)頻率限制,提高服務(wù)穩(wěn)定性。
然后我逐條的分析:
首先,我的簽名算法是沒問題的,直接copy的官方案例;
其次,config中參數(shù)與用以簽名中的對(duì)應(yīng)參數(shù)是完全一致的,因?yàn)樗械膮?shù)都是由返回的,簽名時(shí)用的什么參數(shù),返回的就是什么,所以這點(diǎn)也沒問題。
然后,因?yàn)閡rl是由php文件獲取的,獲取的方法是官方案例中的,所以肯定也沒問題;

再然后,config 中的 appid 與用來獲取 jsapi_ticket 的 appid 是完全一致的,這個(gè)我檢查過;
最后,緩存機(jī)制是在直接copy的官方代碼,這個(gè)肯定也沒錯(cuò)。
那么問題來了,錯(cuò)誤到底出在哪兒?
我又把代碼逐字逐句的檢查,發(fā)現(xiàn)都沒問題。
后來我想了很久,突然之間靈光一閃想到:會(huì)不會(huì)有可能是因?yàn)檎?qǐng)求配置信息的URL跟注入配置信息時(shí)的URL不一樣的原因。
因?yàn)楣俜降膁emo案例中,是前后端不分離的,請(qǐng)求配置信息和注入配置信息時(shí)在同一個(gè)文件,所有URL肯定是不變的。
可是當(dāng)我前后端分離后,請(qǐng)求配置信息的URL是www.demo.com/wx/php/interface.php,然后在注入配置信息的時(shí)候使用的也是這個(gè)URL。
但微信檢測到注入配置信息的請(qǐng)求是由www.demo.com/wx/www/index.html發(fā)送過來的,所以判定URL不一樣,驗(yàn)證失敗。
想到這個(gè)可能,于是我又想到:如果我把請(qǐng)求配置信息時(shí)后端獲得的URL變成www.demo.com/wx/www/index.html,那么問題是不是就解決了。
想到就做,修改URL的獲取方式,由原來的拼接當(dāng)前頁面的URL地址變成現(xiàn)在獲取前一頁面的URL地址。

修改完之后,重新部署項(xiàng)目,問題完美解決!