工作中开发微信网站,简称微网站。由于微网站的分享内容是系统自动选取的当前网址,客户需要改变分享的内容,即点击屏幕右上角的分享按钮,选择发送给朋友和发送到朋友圈,其中的内容和图片需要自定义。于是查找文档微信js-sdk说明文档一文和网站众多高手的经验,大体知道了调用的步骤,但是具体如何调用才能成功却是不了解的。经过一番试验,终于成功调用发送朋友和发送到朋友圈两个接口,此处记录调用的具体过程。
步骤一:引用js文件。
在需要调用js接口的页面引入如下js文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
步骤二:通过config接口注入权限验证配置
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appid: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 noncestr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名,见附录1 jsapilist: [] // 必填,需要使用的js接口列表,所有js接口列表见附录2 });
网上众多网友也是这样写的,但是具体如果配却谈之甚少,接下来介绍本文是如何调用的。
debug和appid,都不用说,很简单。
timespan生成签名的时间戳:
/// 631fb227578dfffda61e1fa4d04b7d25 /// 生成时间戳 /// 从 1970 年 1 月 1 日 00:00:00 至今的秒数,即当前的时间,且最终需要转换为字符串形式 /// 039f3e95db2a684c7b74365531eb6044 /// 2363942ed0d6cd3e85bae1dffa568116f7735d9f6a7af371769ab5c16d23b2f3 public string gettimestamp() { timespan ts = datetime.utcnow - new datetime(1970, 1, 1, 0, 0, 0, 0); return convert.toint64(ts.totalseconds).tostring(); }
noncestr生成签名的随机串:
/// 631fb227578dfffda61e1fa4d04b7d25 /// 生成随机字符串 /// 039f3e95db2a684c7b74365531eb6044 /// 2363942ed0d6cd3e85bae1dffa568116f7735d9f6a7af371769ab5c16d23b2f3 public string getnoncestr() { random random = new random(); return md5util.getmd5(random.next(1000).tostring(), gbk); }
/// 631fb227578dfffda61e1fa4d04b7d25 /// md5util 的摘要说明。 /// 039f3e95db2a684c7b74365531eb6044 public class md5util { public md5util() { // // todo: 在此处添加构造函数逻辑 // } /** 获取大写的md5签名结果 */ public static string getmd5(string encypstr, string charset) { string retstr; md5cryptoserviceprovider m5 = new md5cryptoserviceprovider(); //创建md5对象 byte[] inputbye; byte[] outputbye; //使用gb2312编码方式把字符串转化为字节数组. try { inputbye = encoding.getencoding(charset).getbytes(encypstr); } catch (exception ex) { inputbye = encoding.getencoding(gb2312).getbytes(encypstr); } outputbye = m5.computehash(inputbye); retstr = system.bitconverter.tostring(outputbye); retstr = retstr.replace(-, ).toupper(); return retstr; } }
view code
/// <summary> /// md5util 的摘要说明。 /// </summary> public class md5util { public md5util() { // // todo: 在此处添加构造函数逻辑 // } /** 获取大写的md5签名结果 */ public static string getmd5(string encypstr, string charset) { string retstr; md5cryptoserviceprovider m5 = new md5cryptoserviceprovider(); //创建md5对象 byte[] inputbye; byte[] outputbye; //使用gb2312编码方式把字符串转化为字节数组. try { inputbye = encoding.getencoding(charset).getbytes(encypstr); } catch (exception ex) { inputbye = encoding.getencoding("gb2312").getbytes(encypstr); } outputbye = m5.computehash(inputbye); retstr = system.bitconverter.tostring(outputbye); retstr = retstr.replace("-", "").toupper(); return retstr; } }
singature签名的生成比较麻烦。
首先生成获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token)
public string getaccesstoken() { string appid = system.configuration.configurationmanager.appsettings["wxzjappid"].tostring(); string secret = system.configuration.configurationmanager.appsettings["wxzjappsecret"].tostring(); string urljson = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; string strjson = ""; utf8encoding encoding = new utf8encoding(); httpwebrequest myrequest = (httpwebrequest)webrequest.create(urljson); myrequest.method = "get"; myrequest.contenttype = "application/x-www-form-urlencoded"; httpwebresponse response; stream responsestream; streamreader reader; string srcstring; response = myrequest.getresponse() as httpwebresponse; responsestream = response.getresponsestream(); reader = new system.io.streamreader(responsestream, encoding.utf8); srcstring = reader.readtoend(); reader.close(); if (srcstring.contains("access_token")) { //commonjsonmodel model = new commonjsonmodel(srcstring); hp.cps.bll.weixin.commonjsonmodel model = new bll.weixin.commonjsonmodel(srcstring); strjson = model.getvalue("access_token"); session["access_tokenzj"] = strjson; } return strjson; }
public class commonjsonmodelanalyzer { protected string _getkey(string rawjson) { if (string.isnullorempty(rawjson)) return rawjson; rawjson = rawjson.trim(); string[] jsons = rawjson.split(new char[] { ':' }); if (jsons.length < 2) return rawjson; return jsons[0].replace("\"", "").trim(); } protected string _getvalue(string rawjson) { if (string.isnullorempty(rawjson)) return rawjson; rawjson = rawjson.trim(); string[] jsons = rawjson.split(new char[] { ':' }, stringsplitoptions.removeemptyentries); if (jsons.length < 2) return rawjson; stringbuilder builder = new stringbuilder(); for (int i = 1; i < jsons.length; i++) { builder.append(jsons[i]); builder.append(":"); } if (builder.length > 0) builder.remove(builder.length - 1, 1); string value = builder.tostring(); if (value.startswith("\"")) value = value.substring(1); if (value.endswith("\"")) value = value.substring(0, value.length - 1); return value; } protected list<string> _getcollection(string rawjson) { //[{},{}] list<string> list = new list<string>(); if (string.isnullorempty(rawjson)) return list; rawjson = rawjson.trim(); stringbuilder builder = new stringbuilder(); int nestlevel = -1; int mnestlevel = -1; for (int i = 0; i < rawjson.length; i++) { if (i == 0) continue; else if (i == rawjson.length - 1) continue; char jsonchar = rawjson[i]; if (jsonchar == '{') { nestlevel++; } if (jsonchar == '}') { nestlevel--; } if (jsonchar == '[') { mnestlevel++; } if (jsonchar == ']') { mnestlevel--; } if (jsonchar == ',' && nestlevel == -1 && mnestlevel == -1) { list.add(builder.tostring()); builder = new stringbuilder(); } else { builder.append(jsonchar); } } if (builder.length > 0) list.add(builder.tostring()); return list; } } public class commonjsonmodel : commonjsonmodelanalyzer { private string rawjson; private bool isvalue = false; private bool ismodel = false; private bool iscollection = false; public commonjsonmodel(string rawjson) { this.rawjson = rawjson; if (string.isnullorempty(rawjson)) throw new exception("missing rawjson"); rawjson = rawjson.trim(); if (rawjson.startswith("{")) { ismodel = true; } else if (rawjson.startswith("[")) { iscollection = true; } else { isvalue = true; } } public string rawjson { get { return rawjson; } } public bool isvalue() { return isvalue; } public bool isvalue(string key) { if (!ismodel) return false; if (string.isnullorempty(key)) return false; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); return submodel.isvalue(); } } return false; } public bool ismodel() { return ismodel; } public bool ismodel(string key) { if (!ismodel) return false; if (string.isnullorempty(key)) return false; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); return submodel.ismodel(); } } return false; } public bool iscollection() { return iscollection; } public bool iscollection(string key) { if (!ismodel) return false; if (string.isnullorempty(key)) return false; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); return submodel.iscollection(); } } return false; } /// <summary> /// 当模型是对象,返回拥有的key /// </summary> /// <returns></returns> public list<string> getkeys() { if (!ismodel) return null; list<string> list = new list<string>(); foreach (string subjson in base._getcollection(this.rawjson)) { string key = new commonjsonmodel(subjson).key; if (!string.isnullorempty(key)) list.add(key); } return list; } /// <summary> /// 当模型是对象,key对应是值,则返回key对应的值 /// </summary> /// <param name="key"></param> /// <returns></returns> public string getvalue(string key) { if (!ismodel) return null; if (string.isnullorempty(key)) return null; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) return model.value; } return null; } /// <summary> /// 模型是对象,key对应是对象,返回key对应的对象 /// </summary> /// <param name="key"></param> /// <returns></returns> public commonjsonmodel getmodel(string key) { if (!ismodel) return null; if (string.isnullorempty(key)) return null; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); if (!submodel.ismodel()) return null; else return submodel; } } return null; } /// <summary> /// 模型是对象,key对应是集合,返回集合 /// </summary> /// <param name="key"></param> /// <returns></returns> public commonjsonmodel getcollection(string key) { if (!ismodel) return null; if (string.isnullorempty(key)) return null; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); if (!submodel.iscollection()) return null; else return submodel; } } return null; } /// <summary> /// 模型是集合,返回自身 /// </summary> /// <returns></returns> public list<commonjsonmodel> getcollection() { list<commonjsonmodel> list = new list<commonjsonmodel>(); if (isvalue()) return list; foreach (string subjson in base._getcollection(rawjson)) { list.add(new commonjsonmodel(subjson)); } return list; } /// <summary> /// 当模型是值对象,返回key /// </summary> private string key { get { if (isvalue()) return base._getkey(rawjson); return null; } } /// <summary> /// 当模型是值对象,返回value /// </summary> private string value { get { if (!isvalue()) return null; return base._getvalue(rawjson); } } }
view code
public class commonjsonmodelanalyzer { protected string _getkey(string rawjson) { if (string.isnullorempty(rawjson)) return rawjson; rawjson = rawjson.trim(); string[] jsons = rawjson.split(new char[] { ':' }); if (jsons.length < 2) return rawjson; return jsons[0].replace("\"", "").trim(); } protected string _getvalue(string rawjson) { if (string.isnullorempty(rawjson)) return rawjson; rawjson = rawjson.trim(); string[] jsons = rawjson.split(new char[] { ':' }, stringsplitoptions.removeemptyentries); if (jsons.length < 2) return rawjson; stringbuilder builder = new stringbuilder(); for (int i = 1; i < jsons.length; i++) { builder.append(jsons[i]); builder.append(":"); } if (builder.length > 0) builder.remove(builder.length - 1, 1); string value = builder.tostring(); if (value.startswith("\"")) value = value.substring(1); if (value.endswith("\"")) value = value.substring(0, value.length - 1); return value; } protected list<string> _getcollection(string rawjson) { //[{},{}] list<string> list = new list<string>(); if (string.isnullorempty(rawjson)) return list; rawjson = rawjson.trim(); stringbuilder builder = new stringbuilder(); int nestlevel = -1; int mnestlevel = -1; for (int i = 0; i < rawjson.length; i++) { if (i == 0) continue; else if (i == rawjson.length - 1) continue; char jsonchar = rawjson[i]; if (jsonchar == '{') { nestlevel++; } if (jsonchar == '}') { nestlevel--; } if (jsonchar == '[') { mnestlevel++; } if (jsonchar == ']') { mnestlevel--; } if (jsonchar == ',' && nestlevel == -1 && mnestlevel == -1) { list.add(builder.tostring()); builder = new stringbuilder(); } else { builder.append(jsonchar); } } if (builder.length > 0) list.add(builder.tostring()); return list; } } public class commonjsonmodel : commonjsonmodelanalyzer { private string rawjson; private bool isvalue = false; private bool ismodel = false; private bool iscollection = false; public commonjsonmodel(string rawjson) { this.rawjson = rawjson; if (string.isnullorempty(rawjson)) throw new exception("missing rawjson"); rawjson = rawjson.trim(); if (rawjson.startswith("{")) { ismodel = true; } else if (rawjson.startswith("[")) { iscollection = true; } else { isvalue = true; } } public string rawjson { get { return rawjson; } } public bool isvalue() { return isvalue; } public bool isvalue(string key) { if (!ismodel) return false; if (string.isnullorempty(key)) return false; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); return submodel.isvalue(); } } return false; } public bool ismodel() { return ismodel; } public bool ismodel(string key) { if (!ismodel) return false; if (string.isnullorempty(key)) return false; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); return submodel.ismodel(); } } return false; } public bool iscollection() { return iscollection; } public bool iscollection(string key) { if (!ismodel) return false; if (string.isnullorempty(key)) return false; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); return submodel.iscollection(); } } return false; } /// <summary> /// 当模型是对象,返回拥有的key /// </summary> /// <returns></returns> public list<string> getkeys() { if (!ismodel) return null; list<string> list = new list<string>(); foreach (string subjson in base._getcollection(this.rawjson)) { string key = new commonjsonmodel(subjson).key; if (!string.isnullorempty(key)) list.add(key); } return list; } /// <summary> /// 当模型是对象,key对应是值,则返回key对应的值 /// </summary> /// <param name="key"></param> /// <returns></returns> public string getvalue(string key) { if (!ismodel) return null; if (string.isnullorempty(key)) return null; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) return model.value; } return null; } /// <summary> /// 模型是对象,key对应是对象,返回key对应的对象 /// </summary> /// <param name="key"></param> /// <returns></returns> public commonjsonmodel getmodel(string key) { if (!ismodel) return null; if (string.isnullorempty(key)) return null; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); if (!submodel.ismodel()) return null; else return submodel; } } return null; } /// <summary> /// 模型是对象,key对应是集合,返回集合 /// </summary> /// <param name="key"></param> /// <returns></returns> public commonjsonmodel getcollection(string key) { if (!ismodel) return null; if (string.isnullorempty(key)) return null; foreach (string subjson in base._getcollection(this.rawjson)) { commonjsonmodel model = new commonjsonmodel(subjson); if (!model.isvalue()) continue; if (model.key == key) { commonjsonmodel submodel = new commonjsonmodel(model.value); if (!submodel.iscollection()) return null; else return submodel; } } return null; } /// <summary> /// 模型是集合,返回自身 /// </summary> /// <returns></returns> public list<commonjsonmodel> getcollection() { list<commonjsonmodel> list = new list<commonjsonmodel>(); if (isvalue()) return list; foreach (string subjson in base._getcollection(rawjson)) { list.add(new commonjsonmodel(subjson)); } return list; } /// <summary> /// 当模型是值对象,返回key /// </summary> private string key { get { if (isvalue()) return base._getkey(rawjson); return null; } } /// <summary> /// 当模型是值对象,返回value /// </summary> private string value { get { if (!isvalue()) return null; return base._getvalue(rawjson); } } }
接着获取jsapi_ticket:
用第一步拿到的access_token 采用http get方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket)
public string getjsapi_ticket() { string accesstoken = (string)session["access_tokenzj"]; string urljson = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesstoken + "&type=jsapi"; string strjson = ""; utf8encoding encoding = new utf8encoding(); httpwebrequest myrequest = (httpwebrequest)webrequest.create(urljson); myrequest.method = "get"; myrequest.contenttype = "application/x-www-form-urlencoded"; httpwebresponse response = myrequest.getresponse() as httpwebresponse; stream responsestream = response.getresponsestream(); streamreader reader = new system.io.streamreader(responsestream, encoding.utf8); string srcstring = reader.readtoend(); reader.close(); if (srcstring.contains("ticket")) { hp.cps.bll.weixin.commonjsonmodel model = new bll.weixin.commonjsonmodel(srcstring); strjson = model.getvalue("ticket"); session["ticketzj"] = strjson; } return strjson; }
最后生成signature:
public string getsignature(string noncestr, string timespanstr) { if (session["access_tokenzj"] == null) { getaccesstoken(); } if (session["ticketzj"] == null) { getjsapi_ticket(); } string url = request.url.tostring(); string str = "jsapi_ticket=" + (string)session["ticketzj"] + "&noncestr=" + noncestr + "×tamp=" + timespanstr + "&url=" + url;// +"&wxref=mp.weixin.qq.com"; string singature = sha1util.getsha1(str); string ss = singature; return ss; }
class sha1util { public static string getsha1(string str) { //建立sha1对象 sha1 sha = new sha1cryptoserviceprovider(); //将mystr转换成byte[] asciiencoding enc = new asciiencoding(); byte[] datatohash = enc.getbytes(str); //hash运算 byte[] datahashed = sha.computehash(datatohash); //将运算结果转换成string string hash = bitconverter.tostring(datahashed).replace("-", ""); return hash; } }
class sha1util { public static string getsha1(string str) { //建立sha1对象 sha1 sha = new sha1cryptoserviceprovider(); //将mystr转换成byte[] asciiencoding enc = new asciiencoding(); byte[] datatohash = enc.getbytes(str); //hash运算 byte[] datahashed = sha.computehash(datatohash); //将运算结果转换成string string hash = bitconverter.tostring(datahashed).replace("-", ""); return hash; } }
view code
本文调用实例:
<script type="text/javascript"> wx.config({ debug: false, appid: '<%=corpid %>', timestamp: <%=timestamp%>, noncestr: '<%=noncestr%>', signature: '<%=signature %>', jsapilist: ['onmenusharetimeline', 'onmenushareappmessage'] }); </script>
步骤三:调用接口
在进行完第二步的调用后,步骤三就显得非常轻巧了。
wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。});
本文的调用实例是:
<script type="text/javascript" > wx.ready(function () { wx.onmenushareappmessage({ title: '<%=sharetitle %>', desc: '<%=sharecontent %>', link: '<%=currenturl %>', imgurl: '<%=shareimageurl %>' }); wx.onmenusharetimeline({ title: '<%=sharecontent %>', link: '<%=currenturl %>', imgurl: '<%=shareimageurl %>' }); }) </script>
<script type="text/javascript" > wx.ready(function () { wx.onmenushareappmessage({ title: '<%=sharetitle %>', desc: '<%=sharecontent %>', link: '<%=currenturl %>', imgurl: '<%=shareimageurl %>' }); wx.onmenusharetimeline({ title: '<%=sharecontent %>', link: '<%=currenturl %>', imgurl: '<%=shareimageurl %>' }); }) </script>
本文基本上总结到此处。
易出现的问题:
1、检查后台是否设置:右上角公众号名称--功能设置--js接口安全域名
2、检查代码里的appid和公众号后台的id是否一致
3、图片的调用地址是绝对路径(相对路径好像不行)。
更多微信开发笔记-调用自定义分享接口。
