这是第一次接触微信开发,需要做一次微信活动,主要还是html5+js开发,但需要用一些微信的js-sdk及后端sdk,而此次需要的实现的功能比较简单,需要做上传图片和微信分享。
1.js-sdk的引入
可以直接在页面里引入
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js(需要支持ie8及以下的, 请使用 http://res.wx.qq.com/open/js/jweixin-1.1.0.js)
请注意,如果你的页面启用了https,务必引入 https://res.wx.qq.com/open/js/jweixin-1.0.0.js ,否则将无法在iOS9.0以上系统中成功使用JSSDK
如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js
备注:支持使用 AMD/CMD 标准模块加载方法加载
这里我用的是amd的方式引入,用的require.js
配置如下
var require = {
baseUrl: "/",
urlArgs: 'v=2016011601',
waitSeconds: 0,
paths: {
wx:['http://res.wx.qq.com/open/js/jweixin-1.0.0','Assets/vendor/wx/jweixin-1.0.0'],//支持cdn引入
root: 'wxactivity/20160115/root',
text: 'Assets/vendor/require/text',
domReady: 'Assets/vendor/require/domReady',
css: 'Assets/vendor/require/css'
},
priority: ['text', 'css']};
在做这个之前,我看了下js-sdk的demo,在手机微信中打开,并利用fiddler进行代理查看请求,发现个很奇怪的问题,虽然它的页面引入了js-sdk,但是并无此文件请求,可能是直接将此文件放在本地了。我写好requirejs的配置后,开始查看是否正确引入了js-sdk,暴露出来了一个wx的变量,继续走fiddler,发现同一页面第二次打开时,即使我加上版本参数,也不会再次请求相关js文件。
2.微信分享
配置js-sdk
wx.config({
debug: false,//开发时可设为true
appId: appid,
timestamp: timestamp,
nonceStr: nonceStr,
signature: signature,
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'hideMenuItems'
] //需要用到的api必须在此列出来,若未列出,后面使用会出错
});
我做的并不是单页应用,所以我希望做一个公共的分享函数,但其中有一个模块需求不一样,于是我写下如下代码
var wx_share = function(title,imgUrl,desc,link,callback){
var base = {
title: title,
link: link,
imgUrl: imgUrl,
success: function () {
callback && callback();
};
//分享到朋友圈
wx.onMenuShareTimeline(base);
//分享给朋友
wx.onMenuShareAppMessage(base);
};
wx.ready(function(){
wx.hideMenuItems({
menuList: ["menuItem:share:qq","menuItem:share:weiboApp","menuItem:share:QZone",'menuItem:openWithQQBrowser',
'menuItem:openWithSafari']
});
if(module_name !='info')
vm.wx_share() });
并在info模块自己写了一个调用分享的模块,但配置文件还是用的公共的
自己测试的感觉好好的,但提交测试后,测试说怎么info页面第一次进来分享会失败,分享标题变成了页面标题,无图片,描述变成了页面url。再次去看js-sdk开发文档,看到了这样的一句话,所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用
于是,我在info页面重新注入配置信息,这时分享成功了,但测试又说苹果可以了,但安卓不行啊,继续调试,打开debug选项,发现所有api都已注入成功,但就是不成功,各种崩溃,继续看文档,又看到了一条重要信息,
config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。但我的分享是用户触发时才调用的啊,我需要先调后台api获得数据才能生成分享相关信息,所以我在info页面并没有写在ready内,此时也没其他办法,将其放入ready内,分享成功。结果活动上线后,上午分享还好好的,下午突然所有设备分享都失败,此时内心是崩溃的,继续打开debug,利用fiddler本地调试,发现微信签名全部失败,虽然可以分享,但标题、描述、图片均不是自定义的,分享成功的回调函数也无法执行,因为已经上线,此次活动主要是分享,吸引人气,领导要求必须尽快修复。后台api是另外一个同事写的,刚好那天他又不在,我去查看api代码,发现他只缓存了access_token,而未缓存ticket,用户每次访问,都从微信服务器拿ticket,而文档并未填写调用数量,此时我拿到错误的状态码45009,说明已经超过调用api限制。只能次日才能重置。经过其他同事的测试发现,微信分享默认以页面标题作为标题,页面中第一个img作为图片,描述默认是页面url。我马上调整页面标题及首个img。
3.上传图片
本来我准备使用js-sdk来上传图片,但文档里的一句话使我断了这个念头,上传图片有效期3天,可用微信多媒体接口下载图片到自己的服务器。并不能自己指定保存的服务器,还有有效期,而且下载还有限制。我只能苦逼的自己写了。
小结
由于是针对于手机的,可以使用html5+css3,做弹出框的时候就不需要自己算位置了,直接fixed搞定了。还用r.js对js做了打包,唉,导致我写的根据页面引入相关js没用了,
require(['root'],function(root){
var module_name = root.getModule('index');
root.init();
require(['domReady!','wxactivity/2016/modules/'+module_name],function(domReady,module){
//初始化操作
});
});
注意r.js不支持fallback选项,
附上我的r.js的一个build配置文件
({
baseUrl: ".",
name: "index-r",
paths: {
'jquery': 'vendor/jquery/jquery-1.7.1.min',
'api': 'vendor/utils/api',
'domReady': 'vendor/require/domReady',
'avalon': 'vendor/avalon/avalon',
'jquery.timeago' : 'vendor/jquery/jquery.timeago',
'jquery.floatDiv': 'vendor/jquery/jquery.floatDiv',
'Base64': 'vendor/base64/base64',
'config': './config',
'css': 'vendor/require/css',
'mmAnimate': 'vendor/avalon/mmAnimate',
'avalon.cookie':'vendor/avalon/avalon.cookie',
},
shim: {
'avalon':['config', 'domReady'],
'modules/index/index':['jquery.timeago']
},
out: "index-dist.js"
})
然后在当前目录运行node r.js -o index-build.js