Next.js 12新版Middleware API中如何将变量从中间件传递到页面
结论
不可以直接通过NextResponse.next()方法传递自定义JSON数据,Next.js Middleware目前没有提供类似Express中res.locals的直接透传自定义数据到页面组件的内置能力。
可用实现方案
下面提供2种生产环境常用的实现方式:
方案1:自定义请求头传递(官方推荐,适合单次请求临时数据传递)
实现逻辑:在Middleware中将需要传递的session数据序列化后写入自定义请求头,在页面的getServerSideProps中读取请求头并反序列化后传给页面组件。
修改后的/app/_middleware.js代码:
// /app/_middleware.js import { NextResponse } from 'next/server'; export function middleware(req, event) { const res = { isSignedIn: true, session: { firstName: 'something', lastName: 'else' } }; // 模拟身份认证服务商返回的响应 if (res.isSignedIn) { // 构造响应对象 const response = NextResponse.next(); // 将session序列化后转base64写入自定义请求头,避免特殊字符报错 const sessionStr = Buffer.from(JSON.stringify(res.session)).toString('base64'); response.headers.set('x-user-session', sessionStr); return response; } else { // 重定向到登录页 return NextResponse.redirect('/signin'); } }
修改后的/app/index.js代码:
// /app/index.js export default function Home({ session }) { return ( <div> <h1>认证通过!</h1> <p>你好, { session.firstName }</p> </div> ); } export async function getServerSideProps(context) { // 从请求头中读取session数据 const sessionBase64 = context.req.headers['x-user-session']; const session = JSON.parse(Buffer.from(sessionBase64, 'base64').toString()); return { props: { session } } }
方案2:Cookie传递(适合需要跨请求持久的会话数据)
如果session需要跨多个请求使用,可以将数据写入Cookie,服务端和客户端都可以直接读取Cookie内容。注意如果存储敏感数据,需要对内容加密,同时设置HttpOnly、Secure等安全属性避免XSS攻击。
注意事项
- 自定义请求头的大小不能超过8KB,避免触发浏览器/服务器的请求头大小限制
- 不要在请求头/Cookie中明文存储敏感数据,必须做加密处理
- 如果使用Next.js 13+的App Router,可以直接在服务端组件中调用
headers()方法读取自定义请求头,不需要额外写getServerSideProps
内容的提问来源于stack exchange,提问作者Gnusson
相关产品推荐
相关产品推荐

