【微信公众号开发】【10】JSJDK相关
前言:
1,优点:官方提供的,会调用后还算使用方便,不用费劲了解各个原生组件
缺点:使用上有限制(如:上传文件有大小限制),很容易踩坑,部分安卓手机及电脑端不支持pjax
总结:上手容易,坑很多
2,官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 (内容较多)
3,退出页面
4,选择性隐藏右上角的功能按钮
5,自定义分享内容
6,上传图片
7,图片查看
正文:
步骤:绑定域名——引入JS文件——权限验证——通过ready接口处理成功验证/通过error接口处理失败验证 ( 前三步请参照第二章—JS接口安全域名部分 )
1,权限验证
//1.js 入口页面URL,只在主页引用。 //主要为了解决使用pjax的页面,在获取微信授权时,在微信PC端,手机端表现形式不一致的问题 var entryUrl = location.href.split("#")[0]; //2.js 每个页面引用 var wxCount = 0; //获取授权失败后,重新尝试 var WX_URL = "http://" + document.domain; //当前域名 $(function () { //获取授权 var wxUrl = location.href.split("#")[0]; getWxTicket(wxUrl); //微信的签名只认第一个加载的页面的URL,只在入口签名一次在iOS上是可以的,但在安卓有些机型会签名不上,所以保险起见,每个页面都签名一次 }); function getWxTicket(wxUrl){ var url = window.location.href; if(url.indexOf("/index") != -1){ //回退后首页签名不上,此处为特殊处理,应当不需要用到 wxUrl = WX_URL + "/index"; } $.ajax({ type : "post", url : "/getTicket", data : { "url" : wxUrl }, dataType : "json", success : function(data){ var obj = data; wx.config({ debug: false, //开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: obj.appId, //必填,公众号的唯一标识 timestamp: obj.timestamp, //必填,生成签名的时间戳 nonceStr: obj.nonceStr, //必填,生成签名的随机串 signature: obj.signature,//必填,签名,见微信开发文档附录1 jsApiList: ["hideMenuItems","showMenuItems","chooseImage","previewImage","uploadImage","downloadImage","closeWindow", "onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareWeibo","onMenuShareQZone", "scanQRCode", "getLocation"], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.error(function (res) { if(wxCount == 0){ wxCount = 1; getWxTicket(entryUrl); } }); } }); }
2,ready接口/error接口
wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。
对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 });
wx.error(function(res){ // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。 });
3,退出页面
WeixinJSBridge.invoke('closeWindow',{},function(res){});
但由于这个事件有响应时间,所以在还没退出时点回退按钮会退到上一页面
改进的写法:
history.pushState(null, null, document.URL); setTimeout(function(){WeixinJSBridge.invoke('closeWindow',{},function(res){});},1000);
注:不知是否是我采用pjax的原因,部分手机出现进入页面立即闪退而不是点击回退再退出的问题,所以我实际开发中是把没有用这个方法的,直接都是退到入口页面
4,选择性隐藏右上角的功能按钮
wx.ready(function (){ wx.hideMenuItems({ menuList: [ 'menuItem:favorite', 'menuItem:share:qq', 'menuItem:share:QZone', 'menuItem:share:weiboApp', 'menuItem:share:facebook', 'menuItem:openWithQQBrowser', 'menuItem:openWithSafari', 'menuItem:share:email', 'menuItem:originPage', 'menuItem:copyUrl', 'menuItem:share:brand' ] }); wx.showMenuItems({ menuList: [ 'menuItem:addContact' ] }); });
5,自定义分享内容
wx.ready(function (){ //分享给好友 wx.onMenuShareAppMessage({ title: title,//标题 desc: desc,//描述 link: shareUrl,//地址 imgUrl: 'http://XX.png',//分享图片,如果不设定,会读取该页面第一张 type: '', // 分享类型,music、video或link,不填默认为link dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空 success: function () { }, cancel: function () { } }); //分享到朋友圈 wx.onMenuShareTimeline({ title: title,
desc:desc, link: shareUrl, imgUrl: 'http://XX.jpg', success: function () { }, cancel: function () { } }); wx.onMenuShareQQ({ title: title, desc: desc, link: shareUrl, imgUrl: '', success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); wx.onMenuShareWeibo({ title: title, desc: desc, link: shareUrl, imgUrl: '', success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } });
wx.onMenuShareQZone({ title: title, desc: desc, link: shareUrl, imgUrl: '', success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } }); });
6,上传图片(如果只是上传到微信,微信只会保留一段时间的,所以上传后还要下载回本地)
function chooseImage() { var length = $("#img1 li").length;//已经上传的张数 var count = 3-length; if(length < 3){ wx.chooseImage({ count: count, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { var localIds = res.localIds; if(localIds.length == 0){ layer.open({content:"请先选择图片", btn: '我知道了'}); return; } uploadImage(0,localIds.length,localIds,"exercise"); } }); }else{ layer.open({content:"只能上传3张图片哦", btn: '我知道了'}); } };
/** * 该方法用来上传文件 * @param start:本地ID开始的下标(当前上传的图片的下标) * @param end:本地ID的总个数(也就是选择的图片的总个数) * @param IDs:当前批次选择的所有图片在本地ID的集合 * @param source:来源,后台根据这个存入不同的文件夹 * */ function uploadImage(start,end,IDs,source){ if(start<end){ var localId = IDs[start].toString(); wx.uploadImage({ localId: localId, isShowProgressTips: 1,//显示进度条 success: function (res) { var serverId = res.serverId; // 返回图片的服务器端ID serverId = serverId.toString(); //上传到服务器 $.ajax({ type : "POST", url : "downloadMedia", data:{ "mediaId" : serverId, "source" : source, }, success : function(data){ if(data == ""){ layer.open({content:"格式错误", btn: '我知道了'}); return; }else if(data == "false"){ layer.open({content:"access_token失效,请联系开发人员", btn: '我知道了'}); return; }else{ if(source == "issue"){ $("#img1").html("<li data-path="+data+"><img src="+data+" style='cursor:pointer' class='myImg'></li>"); }else{ $("#img1").append("<li data-path="+data+"><img src="+data+" style='cursor:pointer' class='myImg'></li>"); } } }, error : function(){ layer.open({content:"抱歉,图片上传失败,请稍后再试", btn: '我知道了'}); } }); start++; //延迟1s,这1s用来显示图片信息,避免出现连续上传几次最后一次性显示图片的问题 setTimeout(function(){ uploadImage(start,end,IDs,source); },500); } }); } };
@ApiOperation(value = "使用微信上传图片接口后将图片下载回本地", notes = " ", response = Result.class) @RequestMapping(value = "downloadMedia", method = RequestMethod.POST) public String downloadMedia(String mediaId, String appId, String active) throws IOException { logger.info(String.format("downloadMedia mediaId:%s appId:%s active:%s", mediaId, appId, active)); String savePath = dealSavePath(active); //拼接存储路径,视情况而定 String access_token = WeixinUtil.getAccessToken(appId); String requestUrl = String.format(WxConfig.MEDIA_GET_URL, access_token, mediaId); // 拼接请求地址 try { URL url = new URL(requestUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoInput(true); conn.setRequestMethod("GET"); String fileExt = getFileType(conn.getHeaderField("Content-Type")); // 根据内容类型获取扩展名 if (fileExt.equals("") || !fileExt.equals(".jpg")){ return ""; } String fileName = mediaId + fileExt; String filePath = Config.MEDIA_FILE + savePath + fileName; BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); FileOutputStream fos = new FileOutputStream(new File(filePath)); byte[] buf = new byte[8096]; int size = 0; while ((size = bis.read(buf)) != -1) fos.write(buf, 0, size); fos.close(); bis.close(); conn.disconnect(); String realUrl = Config.REAL_MEDIA_DOMAIN + savePath + fileName; logger.info("downloadMedia success, realUrl=" + realUrl); return realUrl; } catch (Exception e) { logger.error("downloadMedia error:" + e.getMessage()); return ""; } }
7,图片查看(这里的图片地址必须要加上域名)
var imgDomain = "https://i.cnblogs.com/"; //当前域名 //单张 $("#pjax-content").on("click", ".my_singleImg",function(event) { var imgArray = []; var oParent = $(this).parent(); var imgSrc = $(this).data("src"); //当前图片路径 var curImageSrc = imgSrc.indexOf("http") != -1 ? imgSrc : imgDomain + imgSrc; if (curImageSrc && !oParent.attr("href")) { var itemSrc = $(this).data("src"); var curItemSrc = itemSrc.indexOf("http") != -1 ? itemSrc : imgDomain + itemSrc; imgArray.push(curItemSrc); wx.previewImage({ current: curImageSrc, urls: imgArray }); } }); //多张 $("#pjax-content").on("click", ".my_moreImg",function(event) { var imgArray = []; var oParent = $(this).parent(); var imgSrc = $(this).data("src"); var curImageSrc = imgSrc.indexOf("http") != -1 ? imgSrc : imgDomain + imgSrc; if (curImageSrc && !oParent.attr("href")) { $(this).parent().find(".my_moreImg").each(function(index, el) { var itemSrc = $(this).data("src"); var curItemSrc = itemSrc.indexOf("http") != -1 ? itemSrc : imgDomain + itemSrc; imgArray.push(curItemSrc); }); wx.previewImage({ current: curImageSrc, urls: imgArray }); } });