2017-04-13 140 views
0

背景koa2 + KOA路由器+ mysql的回头率“未找到”

我使用koa2一些中间件构建一个基本的API框架。但是,当我用 “ctx.body” 送我的路由器响应,客户端总能收到 “未找到”

我的代码

./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; 

然后一个分贝封套(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; 

我的运行结果

当我启动3000端口服务器,然后通过http://localhost:3000/gateway?time=5访问,它总是返回“未找到”。但正如我所见,我已经使用

return ctx.body = { 
       success: true, 
       code: config.code_success 
      } 

发送响应。我调试并发现数据库处理进行得很好,新数据插入得很好。

当我删除数据库插入线,它运作良好,并返回成功信息。

let r = await df(`insert into gateway (g_time, g_result, g_date) values (${time}, '',now())`); 

这有什么错?

非常感谢!

更新2017年4月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() 
     }) 
    } 

} 

我改成了异步/等待方式则一切运作良好。

请问谁能告诉我这个中间件有什么问题?

+0

尝试调用next()在路线的终点。 –

回答

0

我猜你的问题是./db/data-fetcher.js函数。当你打电话时

let r = await df(`insert ....`) 

你的df - 函数应该返回一个承诺。

于是尝试重写你./db/data-fetcher.js这样的(未测试):

const query = require('./async-db') 

function performQuery(sql) { 
    return new Promise((resolve, reject) => { 
     query(sql).then(
      result => { 
       resolve(result) 
      } 
     ) 
    } 
} 

module.exports = performQuery; 

希望有所帮助。

+0

嗨,感谢您的帮助。但它仍然返回“未找到” –

+0

还有一件事,我看到了:在'let/r = await df(...)'之后的'./router/gateway.js'中有'return ctx.body = {...'。这里应该是'ctx.body = {'...所以没有'return' –

0

正确中间件:

function log(ctx) { 
    console.log(ctx.method, ctx.header.host + ctx.url) 
} 

module.exports = function() { 
    return function (ctx, next) { 
     log(ctx); 
     return next() 
    } 
} 

原因:当涉及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