呼叫微信JS-SDK介面上傳圖片

      最近要在微信上做個問卷調查,有個上傳圖片功能,折騰找了半天資料,都不好弄,最終打算呼叫微信提供的上傳圖片介面,實現上傳圖片功能!此功能最大的好處是可以在微信伺服器上暫存圖片,減少本地伺服器圖片的快取,等到最後的提交,在從微信提供的介面中下載圖片到本地伺服器中儲存!

     微信JS-SDK說明文件

概述

微信JS-SDK是微信公眾平臺面向網頁開發者提供的基於微信內的網頁開發工具包。

通過使用微信JS-SDK,網頁開發者可藉助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信使用者提供更優質的網頁體驗。

此文件面向網頁開發者介紹微信JS-SDK如何使用及相關注意事項。

JSSDK使用步驟

步驟一:繫結域名

先登入微信公眾平臺進入“公眾號設定”的“功能設定”裡填寫“JS介面安全域名”。

備註:登入後可在“開發者中心”檢視對應的介面許可權。

步驟二:引入JS檔案

在需要呼叫JS介面的頁面引入如下JS檔案,(支援https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

如需使用搖一搖周邊功能,請引入 http://res.wx.qq.com/open/js/jweixin-1.1.0.js

備註:支援使用 AMD/CMD 標準模組載入方法載入

步驟三:通過config介面注入許可權驗證配置

所有需要使用JS-SDK的頁面必須先注入配置資訊,否則將無法呼叫(同一個url僅需呼叫一次,對於變化url的SPA的web app可在每次url變化時進行呼叫,目前Android微信客戶端不支援pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。

wx.config({

    debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。

    appId: ”, // 必填,公眾號的唯一標識

    timestamp: , // 必填,生成簽名的時間戳

    nonceStr: ”, // 必填,生成簽名的隨機串

    signature: ”,// 必填,簽名,見附錄1

    jsApiList: [] // 必填,需要使用的JS介面列表,所有JS介面列表見附錄2

});

步驟四:通過ready介面處理成功驗證

wx.ready(function(){

    // config資訊驗證後會執行ready方法,所有介面呼叫都必須在config介面獲得結果之後,config是一個客戶端的非同步操作,所以如果需要在頁面載入時就呼叫相關介面,則須把相關介面放在ready函式中呼叫來確保正確執行。對於使用者觸發時才呼叫的介面,則可以直接呼叫,不需要放在ready函式中。

});

步驟五:通過error介面處理失敗驗證

wx.error(function(res){

    // config資訊驗證失敗會執行error函式,如簽名過期導致驗證失敗,具體錯誤資訊可以開啟config的debug模式檢視,也可以在返回的res引數中檢視,對於SPA可以在這裡更新簽名。

});

介面呼叫說明

所有介面通過wx物件(也可使用jWeixin物件)來呼叫,引數是一個物件,除了每個介面本身需要傳的引數之外,還有以下通用引數:

1.success:介面呼叫成功時執行的回撥函式。

2.fail:介面呼叫失敗時執行的回撥函式。

3.complete:介面呼叫完成時執行的回撥函式,無論成功或失敗都會執行。

4.cancel:使用者點選取消時的回撥函式,僅部分有使用者取消操作的api才會用到。

5.trigger: 監聽Menu中的按鈕點選時觸發的方法,該方法僅支援Menu中的相關介面。

備註:不要嘗試在trigger中使用ajax非同步請求修改本次分享的內容,因為客戶端分享操作是一個同步操作,這時候使用ajax的回包會還沒有返回。

以上幾個函式都帶有一個引數,型別為物件,其中除了每個介面本身返回的資料之外,還有一個通用屬性errMsg,其值格式如下:

呼叫成功時:”xxx:ok” ,其中xxx為呼叫的介面名

使用者取消時:”xxx:cancel”,其中xxx為呼叫的介面名

呼叫失敗時:其值為具體錯誤資訊

影象介面

拍照或從手機相簿中選圖介面

wx.chooseImage({

    count: 1, // 預設9

    sizeType: [‘original’, ‘compressed’], // 可以指定是原圖還是壓縮圖,預設二者都有

    sourceType: [‘album’, ‘camera’], // 可以指定來源是相簿還是相機,預設二者都有

    success: function (res) {

        var localIds = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標籤的src屬性顯示圖片

    }

});

預覽圖片介面

wx.previewImage({

    current: ”, // 當前顯示圖片的http連結

    urls: [] // 需要預覽的圖片http連結列表

});

上傳圖片介面

wx.uploadImage({

    localId: ”, // 需要上傳的圖片的本地ID,由chooseImage介面獲得

    isShowProgressTips: 1, // 預設為1,顯示進度提示

    success: function (res) {

        var serverId = res.serverId; // 返回圖片的伺服器端ID

    }

});

備註:上傳圖片有效期3天,可用微信多媒體介面下載圖片到自己的伺服器,此處獲得的 serverId 即 media_id。

下載圖片介面

wx.downloadImage({

    serverId: ”, // 需要下載的圖片的伺服器端ID,由uploadImage介面獲得

    isShowProgressTips: 1, // 預設為1,顯示進度提示

    success: function (res) {

        var localId = res.localId; // 返回圖片下載後的本地ID

    }

});

根據介面文件的說明:

   引入JS後,進行許可權驗證配置,相關的引數值通過Ajax後臺請求獲取到:

    $.ajax({
url: "test.ashx",
data: {
name: "GetWxJsApi",
curUrl: url
},
type: 'post',
dataType: "json",
success: function (data) {
if (data.success == "1") {
var timestamp = data.timestamp;
var noncestr = data.noncestr;
var signature = data.signature;
//通過config介面注入許可權驗證配置
wx.config({
debug: false,
appId: data.appId,
timestamp: timestamp.toString(),
nonceStr: noncestr,   //生成簽名的隨機串
signature: signature,  //簽名
jsApiList: ['chooseImage', 'uploadImage', 'downloadImage']
});
} else {
alert(data.error);
}
}
});

驗證通過後,可以呼叫手機選擇圖片介面

 //拍照或從手機相簿中選圖介面
function wxChooseImage() {
wx.chooseImage({
count: 1,
needResult: 1,
sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,預設二者都有
sourceType: ['album', 'camera'], // 可以指定來源是相簿還是相機,預設二者都有
success: function (data) {
localIds = data.localIds[0].toString(); // 返回選定照片的本地ID列表,localId可以作為img標籤的src屬性顯示圖片
if (rh.tostr(localIds)) {
wxuploadImage(localIds);
}
},
fail: function (res) {
alterShowMessage("操作提示", JSON.stringify(res), "1", "確定", "", "", "");
}
});
}

  選擇圖片成功後,同時呼叫上傳圖片介面,載入圖片,主要要儲存下mediaId欄位

 
 備註:上傳圖片有效期3天,可用微信多媒體介面下載圖片到自己的伺服器!

//上傳圖片介面
function wxuploadImage(e) {
wx.uploadImage({
localId: e, // 需要上傳的圖片的本地ID,由chooseImage介面獲得
isShowProgressTips: 1, // 預設為1,顯示進度提示
success: function (res) {
mediaId = res.serverId; // 返回圖片的伺服器端ID
if (rh.tostr(mediaId)) {
$(".myimg").attr("src", localIds);
}
},
fail: function (error) {
picPath = '';
localIds = '';
alert(Json.stringify(error));
}
});
}

 最後正式入庫的時候,要通過mediaId從騰訊伺服器中,下載到本地伺服器:

$.ajax({
url: "test.ashx",
data: {
name: "getPicInfo",
media: $.trim(mediaId)
},
type: "Get",
dataType: "text",
success: function (data) {
picPath = data;  //picPath 取得圖片的路徑
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("提交失敗"   textStatus);
}
});

通過訪問後臺介面,同時也通過微信介面

var url = string.Format("https://api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}", token, media);
var PicPath = Common.GetWxPic(url, "").ToString();
<pre name="code" class="csharp"> public static string GetWxPic(string url,string data)
{
string path = "";
try
{
ServicePointManager.Expect100Continue = false;
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url   (data == "" ? "" : "?"   data));
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if(response.StatusCode  == HttpStatusCode.OK)
{
string fileName = Common.RightStr(response.Headers["Content-disposition"],"filename=",false).Replace("\"","");
path = "/uploadfile/"   fileName;
Stream responseStream = response.GetResponseStream();
BinaryReader br = new BinaryReader(responseStream);
FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(path), FileMode.Create, FileAccess.Write);
const int buffsize = 1024;
byte[] bytes = new byte[buffsize];
int totalread = 0;
int numread = buffsize;
while (numread != 0)
{
// read from source
numread = br.Read(bytes, 0, buffsize);
totalread  = numread;
// write to disk
fs.Write(bytes, 0, numread);
}
br.Close();
fs.Close();
response.Close();
}
else
{
response.Close();
path = "";
}
}
}
catch (Exception)
{
path = "";
}
return path;
}

儲存圖片到本地伺服器上,即可:

完整程式碼下載