首页 文章

koa2 koa-router mysql继续返回'Not Found'

提问于
浏览
0

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 回答

  • 0

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

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

    你的 df - 函数应该返回一个promise .

    所以尝试重写你的 ./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

    正确的中间件:

    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

相关问题