【问题标题】:How to handle a 404 in Koa 2?如何在 Koa 2 中处理 404?
【发布时间】:2016-08-28 19:21:43
【问题描述】:

我有一个 404.jade 文件,只要有无效的 GET 请求,我就想渲染它。

这是我当前的代码:

app.js

import Koa from 'koa'
import views from 'koa-views'
import serve from 'koa-static'
import rootRoutes from './routes/index'
import userRoutes from './routes/user'

const app = new Koa()

app.use(views(`${__dirname}/views`, { extension: 'jade' }))
app.use(serve(`${__dirname}/public`))
app.use(rootRoutes.routes())
app.use(userRoutes.routes())

app.listen(3000, () => {
  console.log('Server running at http://localhost:3000')
})

export default app

routes/index.js

import Router from 'koa-router'
const router = new Router()

router.get('/', async ctx => {
  await ctx.render('index')
})

router.get('/about', async ctx => {
  await ctx.render('about')
})

export default router

routes/user.js

import Router from 'koa-router'
const router = new Router({ prefix: '/user' })

router.get('/:name', async ctx => {
  const user = ctx.params.name
  await ctx.render('user', { user })
})

export default router

如何处理任何类型的无效 GET 请求并在发生时以某种方式使用 await ctx.render('404')

【问题讨论】:

    标签: javascript node.js http-status-code-404 koa koa-router


    【解决方案1】:

    您可以在app.js 文件中添加自定义middleware

    import Koa from 'koa'
    import views from 'koa-views'
    import serve from 'koa-static'
    import rootRoutes from './routes/index'
    import userRoutes from './routes/user'
    
    const app = new Koa()
    
    app.use(async(ctx, next) => {
      try {
        await next()
        const status = ctx.status || 404
        if (status === 404) {
            ctx.throw(404)
        }
      } catch (err) {
        ctx.status = err.status || 500
        if (ctx.status === 404) {
          //Your 404.jade
          await ctx.render('404')
        } else {
          //other_error jade
          await ctx.render('other_error')
        }
      }
    })
    
    app.use(views(`${__dirname}/views`, { extension: 'jade' }))
    app.use(serve(`${__dirname}/public`))
    app.use(rootRoutes.routes())
    app.use(userRoutes.routes())
    
    app.listen(3000, () => {
      console.log('Server running at http://localhost:3000')
    })
    
    export default app
    

    【讨论】:

    • 这里值得注意的是,ctx.render 仅在使用 koa-views 时可用。否则,该函数在 ctx 上不存在
    【解决方案2】:

    ctx.response.status的默认值为404

    application.js 第 125 行:

    callback() {
        const fn = compose(this.middleware);
    
        if (!this.listeners('error').length) this.on('error', this.onerror);
    
        const handleRequest = (req, res) => {
          res.statusCode = 404;  // defaul
          const ctx = this.createContext(req, res);
          const onerror = err => ctx.onerror(err);
          const handleResponse = () => respond(ctx);
          onFinished(res, onerror);
          return fn(ctx).then(handleResponse).catch(onerror);
        };
    
        return handleRequest;
    }
    

    如果你打电话:

    this.render('index',{});  
    this.send();  
    this.body='';  
    

    状态码会自动改变。
    所以我们可以使用这个:

    app.use(async (ctx, next) => {
        if(parseInt(ctx.status) === 404){
           ctx.status = 404
           ctx.body = {msg:'emmmmmmm, seems 404'};
        }
    })
    

    这里警告,如果你使用koa-router,请确保上面的函数是用app.use(app = new Koa())调用的,而不是router.use

    【讨论】:

      猜你喜欢
      • 2018-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-14
      • 2015-06-19
      • 1970-01-01
      • 2021-07-31
      • 2015-10-08
      相关资源
      最近更新 更多