Background
我正在使用koa2和一些中间件来构建一个基本的api框架 . 但是当我使用“ctx.body”在我的路由器中发送响应时,客户端总是收到“Not Found”
My code
./app.js
const Koa = require('koa');
const app = new Koa();
const config = require('./config');
//Middlewares
const loggerAsync = require('./middleware/logger-async')
const bodyParser = require('koa-bodyparser')
const jsonp = require('koa-jsonp')
app.use(loggerAsync())
app.use(bodyParser())
app.use(jsonp());
//Router
const gateway = require('./router/gateway')
app.use(gateway.routes(), gateway.allowedMethods());
app.use(async(ctx, next) => {
await next();
ctx.response.body = {
success: false,
code: config.code_system,
message: 'wrong path'
}
});
app.listen(3000);
./router/gateway.js
/**
* Created by Administrator on 2017/4/11.
*/
const Router = require('koa-router');
const gateway = new Router();
const df = require('../db/data-fetcher');
const config = require('../config');
const moment = require('moment');
const log4js = require('log4js');
// log4js.configure({
// appenders: { cheese: { type: 'file', filename: 'cheese.log' } },
// categories: { default: { appenders: ['cheese'], level: 'error' } }
// });
const logger = log4js.getLogger('cheese');
logger.setLevel('ERROR');
gateway.get('/gateway', async(ctx, next) => {
let time = ctx.query.time;
if (!time) {
ctx.body = {
success: false,
code: config.code_system,
message: 'Please input running times'
}
} else {
try {
let r = await df(`insert into gateway (g_time, g_result, g_date) values (${time}, '',now())`);
return ctx.body = {
success: true,
code: config.code_success
}
} catch (error) {
logger.error(error.message);
}
}
});
module.exports = gateway;
然后是一个db包装器(mysql)
./db/async-db.js
const mysql = require('mysql');
const config = require('../config');
const pool = mysql.createPool({
host: config.database.HOST,
user: config.database.USERNAME,
password: config.database.PASSWORD,
database: config.database.DATABASE
})
let query = (sql, values) => {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) {
reject(err)
} else {
connection.query(sql, values, (err, rows) => {
if (err) {
reject(err)
} else {
resolve(rows)
}
connection.release()
})
}
})
})
}
module.exports = query
./db/data-fetcher.js
const query = require('./async-db')
async function performQuery(sql) {
let dataList = await query(sql)
return dataList
}
module.exports = performQuery;
My running result
当我在端口3000上启动服务器然后通过http://localhost:3000/gateway?time=5访问时,它总是返回"Not found" . 但正如我所见,我已经习惯了
return ctx.body = {
success: true,
code: config.code_success
}
发送回复 . 我进行了调试,发现数据库处理工作做得很好,新数据插入得很好 .
when I remove that db inserting line, it works well and returns success info.
let r = await df(`insert into gateway (g_time, g_result, g_date) values (${time}, '',now())`);
有什么不对的吗?
非常感谢!
Update 2017/04/27
现在我发现了问题 . 这是由于我的自定义中间件
const loggerAsync = require('./middleware/logger-async')
代码如下 -
function log( ctx ) {
console.log( ctx.method, ctx.header.host + ctx.url )
}
module.exports = function () {
return function ( ctx, next ) {
return new Promise( ( resolve, reject ) => {
// 执行中间件的操作
log( ctx )
resolve()
return next()
}).catch(( err ) => {
return next()
})
}
}
我把它改成async / await方式然后一切都运行良好 .
谁能告诉我这个中间件有什么问题?
2 回答
我想,你的问题是
./db/data-fetcher.js
函数 . 当你打电话的时候你的
df
- 函数应该返回一个promise .所以尝试重写你的
./db/data-fetcher.js
(未经测试):希望有所帮助 .
正确的中间件:
原因:
resolve
时涉及; promise chain was completed;响应已发送给客户 . 虽然中间件仍然存在,但响应已经消失!试着理解
It seems that if you want to use a common function as middleware, you have to return the next function
nodejs(koa):Can't set headers after they are sent