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 并发出新请求。
我是 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 并发出新请求。