Next.js 13中如何将数据从Middleware传递到组件/API?
在Next.js 13 Middleware中传递数据到组件/API的方法
问题背景
我正在尝试Next.js 13的Middleware功能,但不知道如何将数据(比如JWT解析后的payload、当前登录用户信息)从Middleware传递到组件、页面或API中。
之前未使用Next.js自带Middleware时,我会通过以下方式编写中间件,验证JWT后直接将payload传给组件/API:
import {example} from 'middleware/example' const payload = await example(req, res)
但使用Next.js 13 Middleware时,查阅文档仅发现两种返回方式:
- 返回
NextResponse直接中断请求并返回错误JSON:return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) - 返回
NextResponse.next()继续请求链,但无法附带数据。我曾尝试return NextResponse.next({tes: "tes"}),但找不到在组件/API中获取该数据的方法。
我的Middleware代码如下:
if (request.nextUrl.pathname.startsWith('/api/posts')) { const requestHeaders = new Headers(request.headers) const authorization = requestHeaders.get('authorization') if (!authorization) { return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) } const authSplit = authorization.split(' ') const [authType, authToken] = [ authSplit[0], authSplit[1] ] if (authType !== 'Bearer') { return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) } const payload = await verify(authToken) if (!payload) { return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) } return NextResponse.next() }
解决方案
Next.js 13 Middleware中传递数据到后续组件/API的核心方式是通过自定义请求头传递,以下是具体实现:
1. 在Middleware中添加自定义请求头
解析出payload后,将其转为字符串添加到自定义请求头中,再携带修改后的请求头继续请求链:
if (request.nextUrl.pathname.startsWith('/api/posts')) { const requestHeaders = new Headers(request.headers) const authorization = requestHeaders.get('authorization') if (!authorization) { return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) } const authSplit = authorization.split(' ') const [authType, authToken] = [ authSplit[0], authSplit[1] ] if (authType !== 'Bearer') { return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) } const payload = await verify(authToken) if (!payload) { return new NextResponse( JSON.stringify({ success: false, message: 'authentication failed' }), { status: 401, headers: { 'content-type': 'application/json' } } ) } // 将payload转为字符串存入自定义请求头 requestHeaders.set('x-user-payload', JSON.stringify(payload)) // 携带修改后的headers继续请求 return NextResponse.next({ request: { headers: requestHeaders } }) }
2. 在API路由中获取传递的数据
在/api/posts路由里,通过request.headers获取自定义头并解析:
// app/api/posts/route.js export async function GET(request) { const payloadStr = request.headers.get('x-user-payload') const payload = payloadStr ? JSON.parse(payloadStr) : null // 基于payload处理业务逻辑 return new Response(JSON.stringify({ success: true, data: 'posts list', user: payload }), { headers: { 'content-type': 'application/json' } }) }
3. 在App Router组件中获取传递的数据
在服务器组件或客户端组件中,使用Next.js的headers()函数获取自定义头:
// app/posts/page.js import { headers } from 'next/headers' export default async function PostsPage() { const headersList = headers() const payloadStr = headersList.get('x-user-payload') const payload = payloadStr ? JSON.parse(payloadStr) : null return ( <div> <h1>Posts Page</h1> {payload && <p>当前用户: {payload.username}</p>} </div> ) }
注意事项
- 自定义请求头建议以
x-开头,符合HTTP规范 - 由于headers仅支持字符串,传递对象时需用
JSON.stringify()转换,接收时用JSON.parse()解析 - 敏感数据建议仅在HTTPS环境下传递,避免被拦截
内容的提问来源于stack exchange,提问作者Surezluvy
相关产品推荐
相关产品推荐

