最近要在微信上做个问卷调查,有个上传图片功能,折腾找了半天资料,都不好弄,最终打算调用微信提供的上传图片接口,实现上传图片功能!此功能最大的好处是可以在微信服务器上暂存图片,减少本地服务器图片的缓存,等到最后的提交,在从微信提供的接口中下载图片到本地服务器中保存!
概述
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
此文档面向网页开发者介绍微信JS-SDK如何使用及相关注意事项。
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“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 标准模块加载方法加载
所有需要使用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
});
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});
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; }
保存图片到本地服务器上,即可:
完整代码下载