移動端微信圖片上傳

最近做項目,其中有個需求是在微信企業(yè)號上實現(xiàn)圖片上傳操作。一開始我就把重點放在了"移動端圖片上傳"而不是"微信圖片上傳",所以各種查資料,找插件,費(fèi)了好些功夫,實現(xiàn)起來也是各種困難。后來接觸到微信公眾號,稍微了解了一下,才知道利用微信公眾號或者現(xiàn)在已經(jīng)升級為企業(yè)微信的企業(yè)號的API,還是挺簡單的一個功能。下面我就詳細(xì)整理一下整個過程,做個筆記,一方面可以幫助到從未接觸過這個功能的同學(xué),一方面也方便自己日后翻閱。
1、首先進(jìn)入微信公眾平臺,查看JS-SDK開發(fā)文檔。https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
2、開發(fā)文檔有詳細(xì)的步驟說明,但我還是根據(jù)我自己做的過程再稍微記錄一下。
第一步中的綁定安全域名可不做,不會影響功能的實現(xiàn)。我直接從第二部引進(jìn)js文件開始的。當(dāng)我們想要通過微信上傳圖片時,有兩種方法:一種是JS文件調(diào)用,一種是接口調(diào)用。這里用的是第一種,通過引進(jìn)JS文件,然后直接調(diào)用接口,不再使用URL等接口地址。
3、JS文件的引入:

圖1-引進(jìn)JS文件

4、通過config接口注入權(quán)限驗證配置:
這一步尤為重要。

圖2-配置信息

1)在開發(fā)調(diào)試時,可將debug設(shè)為true,這樣可以看到返回的信息,方便調(diào)試bug。但在生產(chǎn)環(huán)境上,記得設(shè)為false。
2)appId是公眾號的唯一標(biāo)識。項目掛靠在哪個公眾號或者企業(yè)號,就去找相關(guān)負(fù)責(zé)人拿到appId,這個是固定的值,沒有改動,也不需要調(diào)用獲取。(服務(wù)器端,也就是后端開發(fā)人員去拿到這個值)
3)除了jsApiList的值需要前端人員根據(jù)需要自己寫以外,其他參數(shù)均需從后端獲取。最重要的是其中的簽名串,有其特定的生成規(guī)則,后端需要根據(jù)一定的規(guī)則,去調(diào)用微信的接口,獲取相關(guān)參數(shù)后生成簽名串,然后再將對應(yīng)的參數(shù)傳給前端。前端人員獲取到這些數(shù)據(jù)信息后,就可以完成配置信息的注入了。

圖3-調(diào)用配置接口

4)可能會遇到的問題,當(dāng)在完成配置信息的注入后,實際開始調(diào)用所需接口時,出現(xiàn)報錯信息:invalid signature,permission denied,此時解決方法如下:
①首選檢查生成簽名串的算法(規(guī)則)是否正確;
② 其次需要特備注意的是:你在利用參數(shù)生成簽名的時候,要對所有待簽名參數(shù)按照字段名的 ASCII 碼從小到大排序(字典序)后,使用 URL 鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串 string1。這里需要注意的是所有參數(shù)名均為小寫字符。
③注意參數(shù)key值大小寫問題;
④生成簽名串時,需要前端人員給后端傳當(dāng)前頁面的URL,但不包括'#'hash后面的部分。注意前端傳值時的格式以及后端接收時的解析方式。
⑤確認(rèn) config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
⑥很重要的一點,確認(rèn)當(dāng)前訪問頁面的URL已經(jīng)被項目掛靠的公眾號或者企業(yè)號授權(quán)訪問。
更多錯誤信息及詳細(xì)解決方法,請參考:https://my.oschina.net/u/2308739/blog/371414
5)jsApiList中需要填寫的接口。(其實按現(xiàn)在這個操作,是不需要下載圖片接口的,因為下載這一操作是由后端實現(xiàn)的。)
圖4-jsApiList中的接口

5、配置信息注入并且成功校驗完之后,就可以在wx.ready接口下操作相關(guān)圖片接口了。

圖5-wx.ready接口

6、在wx.ready下調(diào)用圖片選擇、上傳、預(yù)覽等接口時,直接按照操作的順序調(diào)用即可。但其中涉及到的一個問題是,如果前端沒有自己的后臺,需要和另外一臺服務(wù)器上的后臺進(jìn)行交互,此時在圖片上傳時就需要調(diào)用后端接口,將圖片上傳后生成的文件流,最終得到的mediaId傳給后端,然后讓后端去微信服務(wù)器上下載剛剛上傳的圖片。
7、話不多說,直接上全部代碼。

 /** ******************獲取微信配置數(shù)據(jù)********************** */
      var Url = ""; //服務(wù)器接口路徑
      var oldNet = '';
      var newNet = '';//記錄網(wǎng)絡(luò)狀態(tài)
      var configData;
      $.ajax({
            url: Url + '/GetSignatureInfo',//后端接口名,可自定義。
//            data: {pageUrl: location.href.split('#')[0]},
            type:"get",
            //params意為參數(shù),是自定義的,用以表明這是傳給后臺的數(shù)據(jù)。
            data:{"params":location.href.split('#')[0]},
            contentType:"application/json; charset=utf-8",
            //數(shù)據(jù)類型為jsonp,解決跨域問題。
            dataType:"jsonp",
            //自定義的jsonp回調(diào)函數(shù)名,默認(rèn)為jQuery自動生成的隨機(jī)函數(shù)
            jsonpCallback:"success_jsonpCallback_select",
            //傳遞給請求處理程序或頁面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(默認(rèn)為callback)
            jsonp:"callbackparam",
            success: function (data) {
//            alert(JSON.stringify(data));
              configData = {
                    debug : false, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
                    appId: data.appid, // 必填,公眾號的唯一標(biāo)識
                    timestamp: data.timestamp, // 必填,生成簽名的時間戳
                    nonceStr: data.nonceStr, // 必填,生成簽名的隨機(jī)串
                    signature: data.signature,// 必填,簽名,見附錄1
                    jsApiList : ['chooseImage','previewImage','uploadImage','downloadImage']
                    // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
                };
               
               //step2:注入配置信息
               wx.config(configData);
               //step3:通過ready接口處理成功驗證
               wx.ready(function () {
                   // config信息驗證后會執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來確保正確執(zhí)行。對于用戶觸發(fā)時才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。
//                 alert("執(zhí)行ready方法");
//                 wx.checkJsApi({
//                      jsApiList: ['chooseImage'] // 需要檢測的JS接口列表,所有JS接口列表見附錄2,
//                      success: function(res) {
//                      // 以鍵值對的形式返回,可用的api值true,不可用為false
//                      // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
//                      }
//                 });
                   //接口1:獲取網(wǎng)絡(luò)類型
                    wx.getNetworkType({
                        success: function (res) {
                          oldNet = res.networkType; // 返回網(wǎng)絡(luò)類型2g,3g,4g,wifi
//                        alert("網(wǎng)絡(luò)類型"+ oldNet);
                        }
                      });
                    // 拍照
//                  alert(document.querySelector('.head_portrait'));
                    document.querySelector('.head_portrait').onclick = function (){
                        
                        $("#tips").html("點擊上傳圖片");
                        
                        var img1 = $('#chooseImage1');
                        //接口2:拍照或從手機(jī)相冊中選圖接口
                        wx.chooseImage({
                            count: 1, // 默認(rèn)9
                            sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認(rèn)二者都有
                            sourceType: ['album', 'camera'],//可以指定來源是相冊還是相機(jī),默認(rèn)二者都有
                            success: function (res) {
                                var imgLocalId = res.localIds;//返回選定照片的本地ID列表,localId可以作為img標(biāo)簽的src屬性顯示圖片
//                              alert("imgLocalId=" + imgLocalId);
//                              alert(res.contentType);
                                if(!imgLocalId){
                                    alert(2);
                                    fnPicInfo('',imgLocalId,'choose','fb',JSON.stringify(res));
                                }
                                img1.attr('src',imgLocalId);
                                
                                //選擇圖片之后詢問是否確認(rèn)上傳
                                $("#isupload").css("display","block");
                                
                                //不上傳或者重新選擇
                                $("#isupload_n").click(function(){
                                    $("#isupload").css("display","none");
                                    $("#tips").html("重新選擇");
                                    $("#chooseImage1").src("");
                                });
                                
                                //確認(rèn)上傳
                                $("#isupload_y").click(function(){
                                    
                                    $("#isupload").css("display","none");
                                    
                                    //接口3:上傳圖片接口
                                    wx.uploadImage({
                                        localId: imgLocalId[0], // 需要上傳的圖片的本地ID,由chooseImage接口獲得
                                        isShowProgressTips: 1, // 默認(rèn)為1,顯示進(jìn)度提示
                                        success: function (res) {
                                            if(res.serverId.indexOf("wxLocalResource://")>=0){
                                                mui.alert('',"圖片上傳失敗,請重新上傳!",'');
                                                return;
                                            }
                                            mediaId = res.serverId;
                                            if(!mediaId){
                                              fnPicInfo(mediaId,imgLocalId,'upload','fb',JSON.stringify(res));
                                            } 
                                            img1.attr('src',imgLocalId);
                                            mediaId1 = mediaId;
                                            localId1 = imgLocalId;
                                            //這里再寫一個接口,將mediaId以及其他所需參數(shù)傳到后臺?;卣{(diào)函數(shù)中不需要寫什么信息。
                                            
                                            //準(zhǔn)備請求的參數(shù):班級編碼、mediaId、上傳類型
                                                                                        //注:班級編碼和上傳類型是根據(jù)項目所需上傳的參數(shù),大家可根據(jù)自己的項目定義,但是mediaId肯定是要上傳的。
                                            var requestdata = {     
                                                "classcode": classcode,
                                                "mediaId": mediaId,
                                                "uploadtype": uploadtype
                                            }
                                            alert(JSON.stringify(requestdata));
                                            //調(diào)用圖片上傳接口
                                            post_mediaId(requestdata);
                                        },
                                        fail: function(re){
                                          wx.getNetworkType({
                                          success: function (res) {
                                            $('.hidden_word1').show();
                                            newNet = res.networkType; // 返回網(wǎng)絡(luò)類型2g,3g,4g,wifi
                                            fnPicInfo('','','upload','fb',re);
                                          }
                                        });
                                        }
                                    });
                                });
                            },
                          fail: function(re){
                            alert(JSON.stringify(re));
                            wx.getNetworkType({
                          success: function (res) {
                            $('.hidden_word1').show();
                            newNet = res.networkType; // 返回網(wǎng)絡(luò)類型2g,3g,4g,wifi
                            fnPicInfo('','','choose','fb',re);
                          }
                        });
                          }
                        });
                    };
              })
              
             }
        });
          // 向后臺數(shù)據(jù)庫傳遞照片的相關(guān)信息,根據(jù)實際需求看是否需要傳遞這些信息。
//        function fnPicInfo(sId,lId,opType,businessType,remark) {
//          remark+="||"+oldNet+"||"+newNet;
//          $.ajax({
//              url:Url+'maintainCommon/addWXMediaRecord',
//              data:{
//                serviceId:sId,
//                localId:lId,
//                clientType:navigator.userAgent,
//                opType:opType,
//                businessType:businessType,
//                remark:remark
//              }
//          });
//        } 
    /********************獲取微信配置數(shù)據(jù)結(jié)束********************** */
//向后端傳遞mediaId的值,以便其能到微信服務(wù)器上下載圖片到本地服務(wù)器。
var post_mediaId = function(requestData){
    var server_IP = "服務(wù)器接口地址";  
    $.ajax({
        url: server_IP,
        type:"get",
        //params意為參數(shù),是自定義的,用以表明這是傳給后臺的數(shù)據(jù)。
        data:{"params":JSON.stringify(requestData)},
        contentType:"application/json; charset=utf-8",
        //數(shù)據(jù)類型為jsonp,解決跨域問題。
        dataType:"jsonp",
        //自定義的jsonp回調(diào)函數(shù)名,默認(rèn)為jQuery自動生成的隨機(jī)函數(shù)
        jsonpCallback:"success_jsonpCallback_select",
        //傳遞給請求處理程序或頁面的,用以獲得jsonp回調(diào)函數(shù)名的參數(shù)名(默認(rèn)為callback)
        jsonp:"callbackparam",
        //訪問成功時的回調(diào)函數(shù)
        success: function(respose){
            alert(respose.message);
        },
        error: function(data){
            alert("服務(wù)器連接失敗");
        }
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,979評論 25 709
  • 給提問的開發(fā)者的建議:提問之前先查詢 文檔、通過社區(qū)右上角搜索搜索已經(jīng)存在的問題。 寫一個簡明扼要的標(biāo)題,并且...
    極樂叔閱讀 14,620評論 0 3
  • 起初對于大理的印象還是在還珠格格里肖劍口中的描述:聽說那兒是一個世外桃源,家家有水,戶戶有花......從此,那個...
    小丸子愛吃魚呀閱讀 577評論 0 0
  • 我有一個朋友,是浙江人,就叫她L吧。她年輕時候是個喜歡到處游玩的人。后來聽說她因為喜歡吃福鼎肉片,而定居在了這里,...
    舌尖八閩閱讀 949評論 7 14
  • 本套組件結(jié)合了微信的視覺規(guī)范,為用戶提供更加統(tǒng)一的使用感受。包含: 底部彈出視圖(Dialog)、支付密碼輸入框(...
    R_yan閱讀 2,203評論 0 9

友情鏈接更多精彩內(nèi)容