- 课外知识点总结
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
如var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
关于url解析:
var a = url.parse('http://example.com:8080/one?a=index&t=article&m=default');
console.log(a);
//输出结果:
{
protocol : 'http' ,
auth : null ,
host : 'example.com:8080' ,
port : '8080' ,
hostname : 'example.com' ,
hash : null ,
search : '?a=index&t=article&m=default',
query : 'a=index&t=article&m=default',
pathname : '/one',
path : '/one?a=index&t=article&m=default',
href : 'http://example.com:8080/one?a=index&t=article&m=default'
}
2.对获取accesstoken的程序的分析
var later = require('later');
var https = require('https');
var fs = require('fs');
var appid = "wxddc8bd73c2f07cf1";
var appsecret = "9e69d242a0edadf3585d7395e0b0400a";
var access_token;
later.date.localTime();
console.log("Now:" + new Date());
var sched = later.parse.recur().every(1).hour();
//later.parse.recur()用来创建一个定时器,后面通常还会再加上一系列方法来构建定时器详
//细的参数。除了every(),hour()外还有许多别的,非常好用,详细见
//http://bunkat.github.io/later/parsers.html
next = later.schedule(sched).next(10); //later.shedule(a).next用来计算定时器a从开始到结束的前10个时间点。通常用来打印显示。
console.log(next);
var timer = later.setInterval(test, sched); //这一步把定时器和相应的function绑定好了
setTimeout(test, 2000); //2000ms后执行一次,这是为了让test不用等下一个整点而是可以立即执行一次
function test() {
console.log(new Date());
var options = {
hostname: 'api.weixin.qq.com',
path: '/cgi-bin/token?grant_type=client_credential&appid=' + appid + '&secret=' + appsecret
}; //options是需要向微信服务器发送的http请求(通俗地讲就是向浏览器输入的网址)
var req = https.get(options, function (res) { //httpget用来发送get类型的请求
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
var bodyChunks = ''; //
res.on('data', function (chunk) {
bodyChunks += chunk;
console.log("new bodychunk ", bodyChunks);
}); //接收到数据时(发生data事件时)把数据存入bodychunk字符串
res.on('end', function () {
var body = JSON.parse(bodyChunks);
console.dir(body);
if (body.access_token) {
access_token = body.access_token;
fs.writeFileSync('token.dat',access_token);
console.log(access_token);
} else {
console.dir(body);
}
}); //接收完全部数据时(发生end事件时)执行该段程序,先是把之前的bodychunk字符串解析成body对象,然后提取出body对象的accesstoken属性即可.这里就取到了微信服务器反悔的accesstoken
});
req.on('error', function (e) {
console.log('ERROR: ' + e.message);
}); //一旦之前的http.get发生错误便会执行这段程序,打印错误信息
}
3.对创建menu程序的理解
var https = require('https');
var access_token='iTR2UD-504GNi90zafTjChcJC-IcT-dwwrodf5Ejea49t6dARKcL2fE_AKLVJZ0nbCQjuBZxCLWt9dV_cglJGdWTETrUpEtnm179XAuO0Q2DRXODysF_Ogj1RH28J9cVJPUdACANTY';
var menu = {
"button": [
{
"name": "嘻嘻哈哈",
"sub_button": [
{
"type": "click",
"name": "我的帐户",
"key": "V1001_MY_ACCOUNT"
},
{
"type": "click",
"name": "已投项目",
"key": "V1002_BID_PROJECTS"
},
{
"type": "click",
"name": "回款计划",
"key": "V1003_RETURN_PLAN"
},
{
"type": "click",
"name": "交易明细",
"key": "V1004_TRANS_DETAIL"
},
{
"type": "click",
"name": "注册/绑定",
"key": "V1005_REGISTER_BIND"
}
]
},
{
"type": "view",
"name": "马上投资",
"url": "http://adviser.ss.pku.edu.cn/wx/"
},
{
"name": "送钱活动",
"sub_button": [
{
"type": "view",
"name": "注册送红包",
"url": "http://adviser.ss.pku.edu.cn/wx/bszn/"
},
{
"type": "click",
"name": "邀请好友一起赚钱",
"key": "V1001_GOOD"
},
{
"type": "view",
"name": "加入我们",
"url": "http://www.ss.pku.edu.cn/"
}
]
}
]
};
var post_str = JSON.stringify(menu);
var post_str1 = new Buffer(JSON.stringify(menu)); //先是从对象中解析出json字符串然后转换成buffer.之所以用buffer是因为之后的contentlength需要的是字节数.在node.js中,一个字符串的长度与根据该字符串所创建的缓存区的长度并不相同,因为在计算字符串的长度时,是以文字作为一个单位,而在计算缓存区的长度时,是以字节作为一个单位。
console.log("post_str is"+post_str);
console.log(post_str.toString());
console.log(post_str.length);
var post_options = {
host: 'api.weixin.qq.com',
port: '443',
path: '/cgi-bin/menu/create?access_token=' + access_token,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_str1.length
}
};
var post_req = https.request(post_options, function (response) {//通常用request来执行post类型的请求
var responseText = [];
var size = 0;
response.setEncoding('utf8'); //http协议本身传输的数据就是二进制的,这里只是提前定义了解码方式为utf8,即使没有这一步也不影响(已经试验过,把这段数据用tostring方法处理后得到的数据和加了这步是一样的),只是方便之后的console.log
response.on('data', function (data) {
responseText.push(data);
size += data.length;
});
response.on('end', function () {
console.log(responseText);
//console.log(responseText.toString());
}); //打印传回来的信息
});
// post the data
console.log("1");
post_req.write(post_str); //需要post的具体菜单内容在这句话发送
console.log("2");
post_req.end(); //http.get自带了这句话,就不用写,但前面用的是request所以一定要加这句
5.对自己上次写的返回用户昵称的小应用的解释
var PORT = 9529;
var http = require('http');
var qs = require('qs');
var https = require('https');
var TOKEN = 'yuntu';
var fs =require('fs');
function checkSignature(params, token){
//1. 将token、timestamp、nonce三个参数进行字典序排序
//2. 将三个参数字符串拼接成一个字符串进行sha1加密
//3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
var key = [token, params.timestamp, params.nonce].sort().join('');
var sha1 = require('crypto').createHash('sha1');
sha1.update(key);
return sha1.digest('hex') == params.signature;
}
var server = http.createServer(function (request, response) {
//解析URL中的query部分,用qs模块(npm install qs)将query解析成json
var query = require('url').parse(request.url).query;
var params = qs.parse(query);
console.log("query is"+query);
console.log("params is"+params);
if(!checkSignature(params, TOKEN)){
//如果签名不对,结束请求并返回
response.end('signature fail');
return;
}
if(request.method == "GET"){
//如果请求是GET,返回echostr用于通过服务器有效校验
response.end(params.echostr);
}else{
//否则是微信给开发者服务器的POST请求
var postdata = "";
request.addListener("data",function(postchunk){
postdata += postchunk;
console.log("postdata is"+postdata);
});
//获取到了POST数据
request.addListener("end",function(){
var parseString = require('xml2js').parseString;
parseString(postdata, function (err, result) {
if(!err){ //利用xml2js解析了获取到的post数据(实际就是用户在公众号上发来的消息),解析后可以方便的获取用户的id,发送的消息格式,消息内容等等
var res = replyText(result); //这个function用来通过用户传来的id,消息等信息返回相应的消息。
console.log('Res is'+res);
response.end(res); //把消息返回给用户
}
});
});
}
});
server.listen(PORT);
console.log("Server runing at port: " + PORT + ".");
var name;
function replyText(msg){
if(msg.xml.MsgType[0] !== 'text'){
return ''; //判断用户发送的消息类型是否符合要求
}
console.log("pple2");
var openid=msg.xml.FromUserName[0];
console.log("pple3");
var token=fs.readFileSync('/home/weixinaccesstoken/token.dat');
console.log("token is "+token);
var options = {
hostname: 'api.weixin.qq.com',
path: '/cgi-bin/user/info?access_token=' + token+ '&openid='+ openid
}; //向微信服务器获取用户资料的api接口格式
console.log(options);
var req = https.get(options, function (res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
var bodyChunks = '';
res.on('data', function (chunk) {
bodyChunks += chunk;
console.log("new bodychunk ", bodyChunks);
});
res.on('end', function () {
var body = JSON.parse(bodyChunks);
//console.dir(body);
name= body.nickname; //这部分类似于之前的accesstoken的获取,最后提取到nickname
console.log(name);
});
});
var tmpl = require('tmpl');
var replyTmpl = '<xml>' +
'<ToUserName><![CDATA[{toUser}]]></ToUserName>' +
'<FromUserName><![CDATA[{fromUser}]]></FromUserName>' +
'<CreateTime><![CDATA[{time}]]></CreateTime>' +
'<MsgType><![CDATA[{type}]]></MsgType>' +
'<Content><![CDATA[{content}]]></Content>' +
'</xml>';
return tmpl(replyTmpl, {
toUser: msg.xml.FromUserName[0],
fromUser: msg.xml.ToUserName[0],
type: 'text',
time: Date.now(),
content: name
});
//将要返回的消息通过一个简单的tmpl模板(npm install tmpl)返回微信
}
6.学习上传git
echo "# test2" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/jackliu1994/test2.git
git push -u origin master
最后代码上传到了https://github.com/jackliu1994/test1.git