剛開始接到這個項目時,因為對Angular比較熟悉,所以就選用了Angular6+Ionic4框架構造整個項目,開發界面時一切順利,到了開發微信JS-SDK的時候就有點懵了,網上關于Angular2~6開發微信JS-SDK的案例一個都找不到,這下就不好辦了,這時候再換框架的話就太拖進度了,會被罵死,而且新框架也不一定那么適用。
辛辛苦苦配置好服務器之后,開始開發JS-SDK了,從官方平臺上下載了demo源碼,有Java、node、PHP、pyhon四個版本的代碼,我對PHP比較熟悉,所以直接拿PHP代碼開干。代碼分為四個文件
首先,access_token.php 和 jsapi_ticket.php 兩個文件是用來緩存全局變量access_token,jsapi_ticket和expire_time的。
然后就是jssdk.php,是主要的文件,里面存放的是請求方法,通過調用此處的方法,請求微信JS-SDK的配置信息。
sample.php文件是入口文件,用php語言寫的一個html頁面,令人尷尬的是,這個頁面是直接調用jssdk.php中的方法請求JS-SDK的配置信息,直接使用的,這種前后端不分離的做法,不存在任何的問題。可是當我在開發angular項目的時候,需要前后端分離,那么就要通過http請求一個php文件,然后在這個php文件中調用jssdk.php的方法請求到參數,然后再返回給前端,最后前端獲取到配置信息,直接使用。下面是我寫的php代碼:
從流程上來講這樣是沒問題的,之前的JS安全域名和IP地址白名單都已經配好了的,運行demo代碼的時候也成功獲取到配置信息。但是,當我把項目打包好部署到服務器之后,發現第一個問題:在angular項目中如何注入配置信息?首先,angular組件中肯定是沒wx這個對象的,需要導入微信JS-SDK的js文件:http://res.wx.qq.com/open/js/jweixin-1.4.0.js
一開始,我是在項目的配置文件中導入,但是發現并沒有用,在應用模塊中導入不了wx對象,而且在渲染出來的頁面中并沒有加載到jweixin-1.4.0.js?。
然后我又試著直接在index文件的頭部信息中引入:
這樣引用之后,在渲染出來的頁面中看到有加載到jweixin-1.4.0.js。
但是這時候出現了困擾我的一個問題,那就是如何獲取js文件中的wx對象。angular框架引入第三方框架的時候,是通過導入的方法獲取到對象的,可是現在沒辦法這樣做,那么我要如何獲取到這個wx對象呢?
在網上找了很久,沒發現有Angular6開發微信的案例,很多都是掛羊頭賣狗肉(我一直認為,Angular2~6和Angular1.X不是同一個框架,兩者區別太大)。網上找不到答案后,就只能自己想辦法。后面突然想起之前做混合開發的時候,通過window注入對象由android和IOS調用的例子,我試著打印window對象,發現在加載了jweixin-1.4.0.js之后,wx對象下面掛載了一個wx對象,于是我想到可以通過window獲取wx對象:
嗯? 這樣是可以的,所以說,在加載了JS-SDK接口文件之后,不需要注入,直接從window下獲取wx對象。
本來到了這里,應該就可以請求到配置信息了,事實上配置信息確實請求到了,但是在調用驗證接口的時候提示簽名錯誤。
這我就納悶了,明明配置信息都請求到了,使用的時候又提示錯誤。我想了好久,都不知道什么原因。百度到出現這種錯誤的幾種原因:
1.確認簽名算法正確,可用?http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign?頁面工具進行校驗。
2.確認config中noncestr, timestamp與用以簽名中的對應noncestr, timestamp一致。
3.確認url是頁面完整的url,包括GET參數部分。
4.確認 config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
5.確保一定緩存access_token和jsapi_ticket,可以減少兩次服務器請求加速體驗外,還避免了觸發頻率限制,提高服務穩定性。
然后我逐條的分析:
首先,我的簽名算法是沒問題的,直接copy的官方案例;
其次,config中參數與用以簽名中的對應參數是完全一致的,因為所有的參數都是由返回的,簽名時用的什么參數,返回的就是什么,所以這點也沒問題。
然后,因為url是由php文件獲取的,獲取的方法是官方案例中的,所以肯定也沒問題;
再然后,config 中的 appid 與用來獲取 jsapi_ticket 的 appid 是完全一致的,這個我檢查過;
最后,緩存機制是在直接copy的官方代碼,這個肯定也沒錯。
那么問題來了,錯誤到底出在哪兒?
我又把代碼逐字逐句的檢查,發現都沒問題。
后來我想了很久,突然之間靈光一閃想到:會不會有可能是因為請求配置信息的URL跟注入配置信息時的URL不一樣的原因。
因為官方的demo案例中,是前后端不分離的,請求配置信息和注入配置信息時在同一個文件,所有URL肯定是不變的。
可是當我前后端分離后,請求配置信息的URL是www.demo.com/wx/php/interface.php,然后在注入配置信息的時候使用的也是這個URL。
但微信檢測到注入配置信息的請求是由www.demo.com/wx/www/index.html發送過來的,所以判定URL不一樣,驗證失敗。
想到這個可能,于是我又想到:如果我把請求配置信息時后端獲得的URL變成www.demo.com/wx/www/index.html,那么問題是不是就解決了。
想到就做,修改URL的獲取方式,由原來的拼接當前頁面的URL地址變成現在獲取前一頁面的URL地址。
修改完之后,重新部署項目,問題完美解決!