关注和取消都获取不到XML数据

来源:2-7 第二天 先撸一个自动回复出来

大丢

2017-04-13

config/wechat.txt


libs/utils.js

'use strict'

var fs = require('fs');
var Promise = require('bluebird');


// 读取文件
exports.readFileAsync = function(fpath, encoding){

return new Promise(function(resolve, reject){
fs.readFile(fpath, encoding, function(err, content){
// console.log("err : " + JSON.stringify(err));
if(err){
reject(err);
}
else {

// console.log("content : " + JSON.stringify(content));
resolve(content);
}
})
})
}


// 写入文件
exports.writeFileAsync = function(fpath, content){
return new Promise(function(resolve, reject){
fs.writeFile(fpath, content, function(err){
if(err){
reject(err);
}
else {
resolve();
}
})
})
}


wechat/g.js

'use strict'

var sha1 = require('sha1');
var getRawBody = require('raw-body');
var Wechat = require('./wechat');



// 中间件
module.exports = function(opts){
// 初始化wechat 管理票据的更新
var wechat = new Wechat(opts);

console.log("++++++");
return function *(next){
console.log(this.query);

// 加密逻辑
var token = opts.token;
var signature = this.query.signature;
var nonce = this.query.nonce;
var timestamp = this.query.timestamp;
var echostr = this.query.echostr;
var str = [token, timestamp, nonce].sort().join('');
var sha = sha1(str);

console.log(this.method);
if(this.method === 'GET'){
if(sha === signature){
this.body = echostr + '';
}
else {
this.body = 'get wrong';
}
}
else if(this.method === 'POST'){
if(sha !== signature){
this.body = 'post wrong';
return false;
}

var data = yield getRawBody(this.req, {
length : this.length,
limit : '1mb',
encoding : this.charset
});

console.log('post ' + data.toString());

}
}
}


wechat/wechat.js

'use strict'

var Promise = require('bluebird');
var request = Promise.promisify(require('request'));


var prefix = 'https://api.weixin.qq.com/cgi-bin/'
var api = {
accessToken : prefix + 'token?grant_type=client_credential'
}
//https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

function Wechat(opts){

// 读取和写入票据
var that = this;
this.appID = opts.appID;
this.appSecret = opts.appSecret;
this.getAccessToken = opts.getAccessToken;
this.saveAccessToken = opts.saveAccessToken;

this.getAccessToken()
.then (function(data){

// 读取票据
try {

data = JSON.parse(data)
}
catch(e){

// 捕获异常 更新票据
return that.updateAccessToken();
}

// 判断票据是否在有效期内 检查合法性
if(that.isValidAccessToken(data)){
// 如果合法 传下去
return Promise.resolve(data);
}
else {
// 如果不合法过期 则更新票据
return that.updateAccessToken();
}
})
.then(function(data){   // 最终票据结果

// 把access_token挂到实例上
that.access_token = data.access_token;

// 把过期时间挂到实例上
that.expires_in = data.expires_in;

// 储存票据
that.saveAccessToken(data);
})
};


// 合法性检查
Wechat.prototype.isValidAccessToken = function(data){


// 验证是否存在
if(!data || !data.access_token || !data.expires_in){
return false;
}

var access_token = data.access_token;
var expires_in = data.expires_in;
var now = (new Date().getTime());

if(now < expires_in) {
// 未过期
return  true;
}
else{
// 已过期
return false;
}
}

// 更新票据
Wechat.prototype.updateAccessToken = function(){

var appID = this.appID;
var appSecret = this.appSecret;
var url = api.accessToken + '&appid=' + appID + '&secret=' + appSecret;

return new Promise(function(resolve, reject){
// 向某个服务器发送请求
request({
url : url,
json : true
}).then(function(response){

// console.log(response);

var data = response.body;
var now = (new Date().getTime());

// 过期时间提前20秒更新 考虑网络延迟
var expires_in = now + (data.expires_in - 20)*1000;

// 缩短后的过期时间复制给数据本身
data.expires_in = expires_in;

// 继续向下传递
resolve(data);
})
});

};


module.exports = Wechat;


app.js

'use strict'

var Koa = require('koa');
var path = require('path');

var wechat = require('./wechat/g');
var util = require('./libs/util');


var wechat_file = path.join(__dirname, './config/wechat.txt');

var config = {
wechat : {
appID : 'wx987f75bb63a127b7',
appSecret : '202a0ae869cfffd0cb24d18d32686577',
token : 'whjtest',
getAccessToken : function(){
return util.readFileAsync(wechat_file)
},
saveAccessToken : function(data){
data = JSON.stringify(data);
return util.writeFileAsync(wechat_file, data)
}
}
};


var app = new Koa();

// functioan 后 加 * 生成器函数  是一种可以从中退出并在之后重新进入的函
app.use(wechat(config.wechat));

app.listen(80);
console.log('localhost:80');


package.json

{
"name": "mp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": {
"name": "whj",
"email": "1004609378@qq.com"
},
"license": "ISC",
"dependencies": {
"bluebird": "^3.5.0",
"koa": "^1.2.0",
"sha1": "^1.1.1"
},
"devDependencies": {
"raw-body": "^2.2.0",
"request": "^2.81.0"
}
}


打印出来的内容

localhost:80
{ signature: '483cccc745a6be740609452a7ab25936f98b18cc',
  echostr: '1071629943448784895',
  timestamp: '1492076093',
  nonce: '748994395' }
GET



再之后,无论是关注,取消关注,都没有任何打印出来了



如图,课程有打印出xml的内容,但是我的并没有

http://szimg.mukewang.com/58f453fe0001688c19201035.jpg

写回答

4回答

Scott

2017-04-18

嘿,这就说明不是这块 this.method 下面的代码的问题啊,发过来的请求貌似就不正常呢。


你把代码,先格式缩进处理好,发我邮箱吧 wolf18387@qq.com


我测试一下

0
1
大丢
已发送至您的邮箱, 邮件名为 - 【慕课网】关注和取消都获取不到XML数据-源码
2017-04-18
共1条回复

Scott

2017-04-17

看代码,没看到你用来回复给微信服务器的代码啊,是没有写,还是忘了贴了


关注和取消关注,微信会推送过来数据,你这里接收到推送数据,做相应处理后,再返回给微信服务器,才会流程继续,你再往后面听两节,先不要跟着敲代码,然后回过头来,看下这个地方。

0
4
大丢
回复
Scott
27输出了GET , 进入if(this.method === 'GET'),页面body出现了 "'get wrong'", 说明走到33行就完结了。 method 一直等于GET,不等于POST,所以后面的课程做了也走不到
2017-04-17
共4条回复

Scott

2017-04-14

先把 koa 退回到 1.2.0 试一下


npm i koa@1.2.0 -save

0
4
大丢
回复
Scott
已在问题里补充完毕,麻烦老师了
2017-04-17
共4条回复

Scott

2017-04-13

koa 的版本是多少?

另外用的哪个代理。

我目测代码没问题,后面都不打印了,因为是 http 请求没成功接收,或者是没有成功进入到这个中间件中,感觉是哪个小环节断了


0
2
大丢
按照这个教程 部署的node服务器 直接用IP是可以打开的 https://segmentfault.com/a/1190000004051670?utm_source=tuicool&utm_medium=referral
2017-04-14
共2条回复

7天搞定Node.js微信公众号

Koa框架、ES2015新特性、MongoDB,开发微信公众号

1742 学习 · 787 问题

查看课程