使用 vue2.0 開發微信公眾號下前後端分離的SPA站點的填坑之旅

lscho發表於2019-02-16

目前正在寫一個微信公眾號的小專案,記錄一下遇到的問題和解決方法(主要是前端)。內容持續更新中~

主要實現

前後端分離
前端為 SPA 單頁面
使用微信的JSSDK
微信支付

技術方案

後端使用 php 搭建介面
vux ui框架
vu2.0e全家桶(vue、vue-router、vue-resource、vuex)

問題列表

跨域問題

因為生產環境下是同域名,不存在跨域問題。生產環境配置反向代理解決了跨域。這裡遇到的問題主要是開發環境下,後端和前端分別在兩個 http 伺服器上。因為前端專案直接用 vue-cli 生成,所以用到了 webpack,正好 webpack 的 dev-server 可以設定反向代理。在config/index.js裡找到 dev 下的 proxyTable 配置項,並加入配置即可

    proxyTable: {
      `/api`: {
        target: `http://127.0.0.1:8888`,
        changeOrigin:true,
        pathRewrite:{
            //`^/api`:``
        }
      }        
    }

授權回撥處理

主要是獲取使用者的 openid。因為每個使用者的 openid 固定不變,所以在首次載入時會檢測 store 中是否有openid,如果沒有就跳轉到授權頁面獲取openid再跳轉回來,並寫入 localstorage,並更新 store。

    //檢測url中是否有openid
    if(this.$route.query.openid){
      this.$store.commit(`updateOpenid`,this.$route.query.openid);
    }
    //跳轉授權
    if(!this.$store.state.openid){
      //授權完成後需要攜帶openid引數再跳回來
      window.location.href="/access";
    }

但是實際應用中這樣並不安全,因為直接將 openid 傳回頁面,容易被客戶端篡改。所以更加安全的做法是授權之後生成一個 token 和對應的 openid 存入資料庫,並設定 token 失效時間,不把 openid 直接暴露給前端。前端提交時使用 token,在後端再取出對應的 openid

微信支付

看了下文件,以前是需要用 jssdk 喚起支付,而現在則是把微信 jssdk 內建到了微信的瀏覽器中。可以直接使用 WeixinJSBridge 來喚起支付。當然簽名生成和訂單需要在後端做。而且支付流程似乎也做了更改,以前是把訂單資訊和加密字串同時傳遞到微信伺服器,而現在是先在後端把訂單資訊傳遞給微信伺服器,返回 prepay_id。前端只需要接收 prepay_id 並傳遞就可以了,這樣的話更安全一些。

在前端元件中的程式碼更加簡單化

    pay(){
        let _this=this;
        let jsApiParameters={};
        let onBridgeReady=function(){
            WeixinJSBridge.invoke(
                    `getBrandWCPayRequest`,
                    jsApiParameters,
                    (res)=>{
                        if (res.err_msg == "get_brand_wcpay_request:ok") {
                            _this.alert(`支付成功`);
                            window.location.reload();
                        }
                        if (res.err_msg == "get_brand_wcpay_request:cancel") {
                            _this.alert(`取消支付`);
                            window.location.reload();
                        }
                    }
            );
        }
        let callpay=function(){
            if (typeof WeixinJSBridge == "undefined") {
                if (document.addEventListener) {
                    document.addEventListener(`WeixinJSBridgeReady`, onBridgeReady, false);
                } else if (document.attachEvent) {
                    document.attachEvent(`WeixinJSBridgeReady`, onBridgeReady);
                    document.attachEvent(`onWeixinJSBridgeReady`, onBridgeReady);
                }
            } else {
                onBridgeReady();
            }            
        }
        //請求支付資料
        this.$http.get(`wechat/wxpay?openid=`+this.$store.state.openid+`&id=`+this.$route.params.id)
                .then((response)=>{
                    if(response.body.status==1){
                        jsApiParameters=response.body.data;
                        callpay();
                    }else{
                        _this.alert(response.body.msg);                        
                    }
        });
    }

支付授權目錄問題

因為微信的支付授權目錄要精確到子目錄級別,而 spa 的 url的形式大概為 /wechat/#/show/1、/wechat/#/list/type 這樣,就會產生髮生支付的頁面報支付目錄未定義的問題。針對這個問題可以在根目錄後加加上 ? 符號連結,後面的地址就會被當成引數解析,而不會當成目錄。/wechat/?#/show/1、/wechat?#/list/type,這樣解析出來的目錄都是在 /wechat/ 根目錄下面

安卓下無法使用 html5 input 無法喚起攝像頭

上傳圖片部分使用的是html5直接選擇圖片上傳

<input id="uploaderInput" @change="change" class="weui-uploader__input" type="file" accept="image/*"  multiple />

在 ios 裝置下沒有問題,會彈出選擇拍照、相簿等選項。但是朋友說在安卓下只能選擇相簿,而且無法多選。上網查了一下,確實在部分安卓平臺下有這個問題。加上 capture=camera” 可以直接使用拍照,但是選擇相簿又沒了。。。

解決方案有兩個
1.使用微信的 jssdk 來選擇圖片,但是這樣上傳部分要修改。
2.在安卓下使用 vux 提供的 Actionsheet 元件來代替系統預設的選擇,分別加上選擇相簿、直接開啟拍照。
好氣啊,手頭又沒有安卓裝置,索性先放下不管了。

部落格連結:https://lscho.com/tech/vue-we…,後續在部落格更新

相關文章