【问题标题】:KOA-Views Suddenly Stop Working after First Route第一条路线后,KOA-Views 突然停止工作
【发布时间】:2020-02-29 07:42:31
【问题描述】:

这个项目的完整代码可以找到here: https://github.com/AlexMercedCoder/KoaStarterBlog

我正在制作的视频系列可以在这里找到,这样你就可以看到不同阶段的工作情况:https://www.youtube.com/watch?v=8_aWw7lfKKI&list=PLY6oTPmKnKbbF4t0Y9DcUVYi7f4kix7Qj

我实际上在这个视频的开头部分说明了这个问题,并遍历了我所有路线的构建:https://youtu.be/ltAxokJsaWE

所以我使用 KoaJS 构建了这个基本的博客应用程序。当我最初运行 index.js 时,行为如下。 - 根路线工程 - 创建路线作品 - 管理路线有效 - 删除按钮适用于管理页面 - 编辑路线不会(即使代码与其他路线一样,也可以开启和关闭)

更大的问题:通过点击删除按钮或创建新帖子提交表单后,除了创建路由之外的所有路由都停止工作,而是返回(未找到)。起初我认为这是由 ctx.redirect 引起的问题,因为它们总是会失败,并且会出现损坏的路由,但是在呈现完整页面时,最初在表单提交仍然中断后,在浏览器中键入 root 或 admin 路由似乎可以正常工作。

*更新:这发生在去任何路由之后,如果第一个路由被访问,每条路由都可以工作,但之后除了 create 之外的所有其他路由都停止工作。就好像第一条路线造成了某种不确定性。奇怪的是路由器仍然会在控制台记录路由应该执行的所有操作,直到返回 ctx.render、ctx.redirect 或 ctx.body。

下面是 index.js 代码!

///////////////////////
//Initializing Environment Variables and other middleware
//npm i dotenv
//npm i koa-methodoverride
///////////////////////
require('dotenv').config();
const override = require('koa-methodoverride');
const parser = require('koa-bodyparser');


////////////////////////
//Connecting the DB
//npm i mongoose
////////////////////////
const mongoose = require('mongoose');
const db = mongoose.connection;
const host = process.env.host;
const dbupdate = {
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useFindAndModify: false};
mongoose.connect(host, dbupdate);

db.on('error', (err) => console.log('Error, DB Not connected'));
db.on('connected', () => console.log ('connected to mongo'));
db.on('diconnected', () => console.log ('Mongo is disconnected'));
db.on('open', () =>console.log ('Connection Made!'));

////////////////////////////
//Model Schema
///////////////////////////
const Blog = require('./model/blog.js');


///////////////////////
//Create Our Server Object
//npm i koa
///////////////////////
const koa = require('koa');
const server = new koa();

//////////////////////////
//Create Our Static Folder
//npm i koa-static
//////////////////////////
const static = require('koa-static');

//////////////////////////
//Creating Our Router
//npm i koa-router
//////////////////////////
const Router = require('koa-router');
const route = new Router();

/////////////////////////////////
//initializing views
//npm i koa-views
//npm i nunjucks
////////////////////////////////;
const views = require('koa-views');
const nunj = require('nunjucks');
nunj.configure('./views', {autoescape: true});


///////////////////////////
//routes
// route.get - route.post - route.patch - post.put - route.delete
///////////////////////////

//root route
route.get('/', (ctx, next) => {
    console.log('connected to root route');
    return Blog.find({}, (error, results) => {
        console.log(results)
        ctx.render('index.njk', {
            posts: results
        });
    });
});

//admin route
route.get('/admin', (ctx, next) => {
    console.log('connected to admin route');
    return Blog.find({}, (error, results) => {
        console.log(results)
        ctx.render('admin.njk', {
            posts: results
        });
    });
});

//delete route
route.delete('/delete/:id', (ctx, next) => {
    console.log('connected to delete route');
    console.log(ctx.request.body)
    if (ctx.request.body.pw === process.env.pw){
        Blog.findByIdAndRemove(ctx.params.id, (err, result) => {

       })
    }else{
        console.log('wrong password')

    }
    return ctx.render('complete.njk');
});

//edit route
route.get('/edit/:id', (ctx, next) => {
    console.log('connected to edit route');
    return Blog.findById(ctx.params.id, (err, results) => {
        console.log(results);
        ctx.render('edit.njk', {
        post: results
        });
    });
});

route.put('/edit/:id', (ctx, next) => {
    console.log('editing a post');
    console.log(ctx.request.body)
    if (ctx.request.body.pw === process.env.pw){
        Blog.findByIdAndUpdate(ctx.params.id, ctx.request.body, {new:True}, (err, result) => {
         console.log(result); 
        })
     }else{
         console.log('wrong password');
        }
    return ctx.render('complete.njk');
});

//create route
route.get('/create', (ctx, next) => {
    console.log('connected to create route');
    return ctx.render('create.njk');
});

route.post('/create', (ctx, next) => {
    console.log('creating a post');
    console.log(ctx.request.body)
    if (ctx.request.body.pw === process.env.pw){
        Blog.create(ctx.request.body, (err, result) => {
         console.log(result); 
        })
     }else{
         console.log('wrong password');
        ;
     }
     return ctx.render('complete.njk');
});

////////////////////////////
//Async Functions
////////////////////////////
// const getPosts = async (query) => { 
//     const data = await Blog.find({query}) 
//     return data; 
//   }; 

////////////////////////
//Middleware
/////////////////////////
server.use(parser());
server.use(override('_method'))
server.use(views('./views', {map: {njk: 'nunjucks'}}));
server.use(route.routes());
server.use(static('./public'));




/////////////////////
//Our Listener on Port 1985
/////////////////////
server.listen(1985,'localhost',() => console.log('Listening on port 1985'));

【问题讨论】:

    标签: node.js mongodb mongoose koa nunjucks


    【解决方案1】:

    它看起来像一个 http-server 故障。尝试添加error handler

    我还建议更改代码中的错误处理,例如

    route.put('/edit/:id', (ctx, next) => {
        if (ctx.request.body.pw === process.env.pw){
            Blog.findByIdAndUpdate(ctx.params.id, ctx.request.body, {new:True}, (err, result) => {
             console.log(result); 
            })
         } else {
             console.log('wrong password');
            }
        return ctx.render('complete.njk');
    });
    

    替换为

    route.put('/edit/:id', (ctx, next) => {
      // Early stop to avoid brace ladder
      if (ctx.request.body.pw != process.env.pw)
        ctx.throw('Env. wrong password'); // Pass request to error-handler
    
      Blog.findByIdAndUpdate(ctx.params.id, ctx.request.body, {new:True}, (err, result) => {
        if (err)              
          ctx.throw('Db wrong password'); // or throw Error('Db wrong password');
    
        ctx.render('complete.njk');
      });
    }
    ...
    server.use(route.routes());
    server.use(static('./public'));
    
    // Error handler: catch 'wrong password'-error here.
    app.on('error', (err, ctx) => {
      console.error(err);
      ctx.render('error.njk'); 
    });
    

    附:我使用 Express,而不是 Koa。所以也许我犯了一些错误。


    也许ctx.render 需要async-await 框架,如下所示

    route.get('/', async (ctx, next) => {
        console.log('connected to root route');
        console.log(ctx);
        return Blog.find({}, (error, results) => {
            console.log(results)
            await ctx.render('index', {
                posts: results
            });
            console.log('the view was rendered')
        });
    });
    

    我下载了您的git 并进行了更改。它有效:)

    【讨论】:

    • 将在接下来的几天内试用此功能
    • 试过了,它不起作用,数据库更新和密码部分正在工作,当它运行 ctx.render 时出现问题,它给我 Not Found,但如果我重新启动服务器并刷新它工作。
    • 好的。尝试在开始的日志中间件添加:app.use(async (ctx, next) => {console.log(ctx.request.href, ctx.req.method); await next();});。这个中间件应该适用于每个请求。因此,您可以检测响应何时中断:在路由器之前或之后。
    • 将它添加到我的中间件中,代码照原样运行,但除了我的路由特定控制台日志之外什么都没有运行,我将尝试将这个特定的 console.log 放入路由中。
    • 好的,在路由中运行控制台日志并且输出是正确的,它发出了正确的请求,这与路由中的所有其他内容都运行良好,除了模板的呈现。一旦我启动服务器,它就会渲染模板,但在它停止之后,它不会抛出任何类型的错误,它运行之前和之后的代码都很好,只需注意 ctx.render。
    【解决方案2】:

    我从没想过会导致这种行为,但我能够修复并将工作代码提交到 github 存储库。经过几次尝试后,我无法让 koa-views 库正常工作,所以我放弃了它并切换到 koa-nunjucks-2 并按照文档中的说明对其进行了初始化。

    不幸的是......同样的问题一直发生,直到我使用 path.join 将路径更改为相对路径,然后 koa-nunjucks-2 完美运行!

    为什么,或者发生了什么,我仍然不知道。这可能与幕后未解决的承诺有关,但我不太确定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-22
      • 2021-02-01
      • 2016-12-29
      • 2018-05-09
      • 2015-12-07
      • 2015-08-23
      • 2014-02-05
      相关资源
      最近更新 更多