微信JS-SDK wx.chooseImage選擇並預覽圖片,並上傳到自己服務器


轉自:https://zhuanlan.zhihu.com/p/342672565

 

問題

我想要達成一個選擇完圖片就可以直接預覽的效果,文檔中也寫明了localId可以作為img的src屬性顯示圖片,

我的操作是,選擇完圖片之后,直接將 localId 賦給 img的src屬性,但是結果不顯示

通過搜貼,發現自己忽略了文檔中的這一條信息

 

 

 

不顯示原因有二

  1. 版本低於1.2.0,我使用的是1.0.0
  2. 用 getLocalImgData 接口獲取的數據,蘋果可以直接賦值,但是安卓有一個坑,在拼接前需要對localData進行換行符的全局替換

 

 

 

wx.chooseImage選擇並預覽圖片,並上傳到自己服務器

注意 引入JS文件

// 推薦使用1.3.2以上的版本,之前的版本很多坑 
https://res.wx.qq.com/open/js/jweixin-1.3.2.js
// 也可以用npm包
npm install weixin-js-sdk

1、選擇圖片

wx.chooseImage({
    count: 1, // 默認9
    sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有
    sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有
    success: function (res) {
        var localIds = res.localIds; // array,返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片
    }
});

2、處理圖片數據為base64

wx.chooseImage獲取到的圖片為一個臨時路徑,微信同時提供了wx.getLocalImgData方法可以把獲取到的路徑轉為base64格式的數據,至此就可以輕松許多了,但是轉出來的base64在android和iOS中稍有不同,需要特別注意一下:

wx.getLocalImgData({
          localId: res.localIds[0], // 圖片的localID
          success: function(res) {
            const localData = res.localData;
            let imageBase64 = '';
            if (localData.indexOf('data:image') == 0) {
              //蘋果的直接賦值,默認生成'data:image/jpeg;base64,'的頭部拼接
              imageBase64 = localData;
            } else {
              //此處是安卓中的唯一得坑!在拼接前需要對localData進行換行符的全局替換
              //此時一個正常的base64圖片路徑就完美生成賦值到img的src中了
              imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, '');
            }
            $('#img').attr('src', imageBase64);
          }
        });

3、上傳圖片

獲取到圖片的base64數據之后其實我們就可以為所欲為了,不需要使用wx.uploadImagewx.downloadImage了,不僅需要麻煩的上傳到微信服務器,還有三天的時間限制反而增加了成本,最好的方式就是直接上傳至我們自己的服務器。

一般與服務端交互的這種文件類型一般采用表單提交--multipart/form-data的方式,這就要求我們熟悉傳輸form-data的數據交互,所以需要把剛才獲取到的base64轉為可post的二進制數據,JavaScript提供了原生的atob/btoa用來對base64進行編碼和解碼;

function dataURLtoBlob(dataurl) {
    let arr = dataurl.split(',');
    let mime = arr[0].match(/:(.*?);/)[1];
    let bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {
      type: mime
    });
  };

ok,處理好可交互的數據就可以上傳到自己的服務器了,之后相當於普通H5頁面的圖片交互了,可上傳可下載

  var param = new FormData();
  param.append('headPic', imageData);
  $.ajax({
    url: "http://www.xxx.com/upimg.php", // 填寫你的url地址
    type: "post",
    data: param,
    dataType: 'JSON', // 服務器響應的數據類型
    processData: false, // 因為data值是FormData對象,不需要對數據做處理
    contentType: false, // 告訴jQuery不要去設置Content-Type請求頭
    cache: false, // 上傳文件不需要緩存
    success: function(data) {
      // ...
      alert('請求成功');
    }
  });

后台獲取到的代碼是這樣的

if ($_FILES) {
    file_put_contents('../test.log', json_encode($_FILES));
    echo 1;
}

// {"headPic":{"name":"blob","type":"image\/jpg","tmp_name":"\/tmp\/phpX8kcxh","error":0,"size":37937}}

之后就可以在后台完成上傳代碼的操作的,服務器接收傳過來的圖片並上傳到服務器的操作,請參考 —— 《PHP CURL的用法及上傳圖片》,在最下面的一段代碼

 

完整代碼

我這個是直接在官方示例模板中改寫的,官方示例下載地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#67

  1 <?php
  2 require_once "jssdk.php";
  3 $jssdk = new JSSDK("你的appId", "你的appSecret");
  4 $signPackage = $jssdk->GetSignPackage();
  5 ?>
  6 <!DOCTYPE html>
  7 <html lang="en">
  8 
  9 <head>
 10   <meta charset="UTF-8">
 11   <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
 12   <title></title>
 13 </head>
 14 
 15 <body>
 16   <button id="button2">拍照或從手機相冊中選圖接口</button><br />
 17   <button onclick="updateImg()">確認上傳</button><br />
 18   <img src="" id="img" width="150px" height="150px"><br />
 19 </body>
 20 <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
 21 <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
 22 <script>
 23   /*
 24    * 注意:
 25    * 1. 所有的JS接口只能在公眾號綁定的域名下調用,公眾號開發者需要先登錄微信公眾平台進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”。
 26    * 2. 如果發現在 Android 不能分享自定義內容,請到官網下載最新的包覆蓋安裝,Android 自定義分享接口需升級至 6.0.2.58 版本及以上。
 27    * 3. 常見問題及完整 JS-SDK 文檔地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
 28    *
 29    * 開發中遇到問題詳見文檔“附錄5-常見錯誤及解決辦法”解決,如仍未能解決可通過以下渠道反饋:
 30    * 郵箱地址:weixin-open@qq.com
 31    * 郵件主題:【微信JS-SDK反饋】具體問題
 32    * 郵件內容說明:用簡明的語言描述問題所在,並交代清楚遇到該問題的場景,可附上截屏圖片,微信團隊會盡快處理你的反饋。
 33    */
 34   wx.config({
 35     debug: false, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。
 36     appId: '<?php echo $signPackage["appId"]; ?>', // 必填
 37     timestamp: <?php echo $signPackage["timestamp"]; ?>, // 必填,生成簽名的時間戳
 38     nonceStr: '<?php echo $signPackage["nonceStr"]; ?>', // 必填,生成簽名的隨機串
 39     signature: '<?php echo $signPackage["signature"]; ?>', // 必填,簽名
 40     jsApiList: [ // 必填
 41       // 所有要調用的 API 都要加到這個列表中
 42       'onMenuShareAppMessage',
 43       'chooseImage',
 44       'getLocalImgData'
 45     ]
 46   });
 47   wx.ready(function() {
 48     // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。
 49     // 在這里調用 API
 50   });
 51 
 52   var image_base64 = '';
 53 
 54   $('#button2').click(function() {
 55     var images = {
 56       localId: [],
 57       serverId: []
 58     };
 59     // 選擇圖片
 60     wx.chooseImage({
 61       count: 1, // 默認9
 62       sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有
 63       sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有
 64       success: function(res) {
 65         // wx.chooseImage獲取到的圖片為一個臨時路徑,微信同時提供了wx.getLocalImgData方法可以把獲取到的路徑轉為base64格式的數據,至此就可以輕松許多了,但是轉出來的base64在android和iOS中稍有不同
 66         wx.getLocalImgData({
 67           localId: res.localIds[0], // 圖片的localID
 68           success: function(res) {
 69             const localData = res.localData;
 70             let imageBase64 = '';
 71             if (localData.indexOf('data:image') == 0) {
 72               //蘋果的直接賦值,默認生成'data:image/jpeg;base64,'的頭部拼接
 73               imageBase64 = localData;
 74             } else {
 75               //此處是安卓中的唯一得坑!在拼接前需要對localData進行換行符的全局替換
 76               //此時一個正常的base64圖片路徑就完美生成賦值到img的src中了
 77               imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, '');
 78             }
 79             image_base64 = imageBase64;
 80             $('#img').attr('src', imageBase64);
 81           }
 82         });
 83       }
 84     });
 85   });
 86 
 87   /**
 88    * 點擊上傳圖片按鈕
 89    */
 90   function updateImg() {
 91     if (image_base64 == '') {
 92       alert('請先選擇圖片');
 93       return;
 94     }
 95     handleAvatar(dataURLtoBlob(image_base64));
 96   }
 97 
 98   /**
 99    * ajax上傳圖片
100    */
101   function handleAvatar(imageData) {
102     var param = new FormData();
103     param.append('headPic', imageData);
104     $.ajax({
105       url: "http://www.xxx.com/upimg.php", // 填寫你的url地址
106       type: "post",
107       data: param,
108       dataType: 'JSON', // 服務器響應的數據類型
109       processData: false, // 因為data值是FormData對象,不需要對數據做處理
110       contentType: false, // 告訴jQuery不要去設置Content-Type請求頭
111       cache: false, // 上傳文件不需要緩存
112       success: function(data) {
113         // ...
114         alert('請求成功');
115       }
116     });
117   };
118 
119   /**
120    * base64轉為可post的二進制數據
121    */
122   function dataURLtoBlob(dataurl) {
123     let arr = dataurl.split(',');
124     let mime = arr[0].match(/:(.*?);/)[1];
125     let bstr = atob(arr[1]);
126     let n = bstr.length;
127     let u8arr = new Uint8Array(n);
128     while (n--) {
129       u8arr[n] = bstr.charCodeAt(n);
130     }
131     return new Blob([u8arr], {
132       type: mime
133     });
134   };
135 </script>
136 
137 </html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM