KoaJS ctx.redirect() 在 Chrome 中导致 ERR_TOO_MANY_REDIRECTS

KoaJS ctx.redirect() causing ERR_TOO_MANY_REDIRECTS in Chrome

我是 KoaJS 的新手。现在玩一点。我正在尝试使用中间件将所有请求重定向到特定的 URL。这似乎在 Chrome 中产生了 ERR_TOO_MANY_REDIRECTS。我尝试了很多调试。看不出哪里不对。

index.js

// App
const Koa = require('koa')
const app = new Koa()

// Parser
const bodyParser = require('koa-body')
app.use(bodyParser())

// Session
const session = require('koa-session')
app.keys = ['asdfasdf@#$ASDf1#$@5rasdf']
app.use(session(app))
// THIS MIDDLEWARE
app.use(async (ctx, next) => {
    ctx.session.user = '121' // This is all playground. No production stuff.
    const s = ctx.session.user
    if (s != '1213') {
        ctx.redirect('/login')
    }
    await next()
})

// Router
const common = require('./routes')
app.use(common.routes())

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

routes.js

const Router = require('koa-router')
const router = new Router()

// const User = require('./user')

router.get('/', async ctx => {
    ctx.body = 'Home Page'
})

router.get('/login', async ctx => {
    ctx.body = 'Login Page'
})

module.exports = router

考虑你的中间件:

app.use(async (ctx, next) => {
    ctx.session.user = '121' // This is all playground. No production stuff.
    const s = ctx.session.user
    if (s != '1213') {
        ctx.redirect('/login')
    }
    await next()
})

因为 s != '1213' 总是计算为 "true",ctx.redirect('/login') 被执行 对于每个请求

这将做两件事:

  • 将 HTTP 响应代码设置为 302,告诉浏览器执行重定向
  • Location header 设置为 /login,告诉浏览器要重定向到的位置

考虑到每个请求都会发生这种情况,您最终会陷入循环:对 / 的请求被重定向到 /login,它本身被重定向到 /login,这是也重定向到 /login,无限循环。在某个时候,浏览器放弃并发出 ERR_TOO_MANY_REDIRECTS 错误。

FWIW,在调用 ctx.redirect() 之后,您通常会结束请求,例如:

if (s != '1213') {
    return ctx.redirect('/login')
}

在你的例子中,你没有结束请求,这意味着它将被传递到路由器。

为了回答 your comment,我假设你使用了这个:

if (s != '1213') {
    ctx.url = '/login';
}

您更改 URL 路由器将检查它应该调用哪个处理程序。有点像内部重定向,或 "rewrite":对 / 的请求在 内部 处理,就像对 /login 的请求一样。

但这不是您想要的,因为它可能会混淆浏览器。正确的方法是使用 ctx.redirect() 发出正确的重定向,这将使浏览器更改地址栏中的 URL 并发出新请求。