错误:中间件在响应头已发送后设置了标头 'X'。
Error: Middleware set header 'X' after response headers were already sent.
ID: nextjs/middleware-response-header-override
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| Next.js 13.5 | active | — | — | — |
| Next.js 14.0 | active | — | — | — |
| Next.js 14.2 | active | — | — | — |
| Next.js 15.0 | active | — | — | — |
根因分析
中间件函数在响应已发送或调用 NextResponse.next() 后尝试修改响应头(例如,通过 response.headers.set()),而没有正确克隆响应。
English
The middleware function attempts to modify response headers (e.g., via response.headers.set()) after the response has already been sent or after calling NextResponse.next() without properly cloning the response.
官方文档
https://nextjs.org/docs/app/building-your-application/routing/middleware解决方案
-
在调用 NextResponse.next() 或发送响应之前设置标头。使用带有标头的 NextResponse.rewrite() 或 NextResponse.redirect() 在构造函数中设置。
-
使用 'request' 对象读取标头并在新响应上设置。避免在原始响应被使用后修改它。
-
如果需要有条件地设置标头,创建一个新的 NextResponse 对象,而不是修改 NextResponse.next() 返回的对象。
无效尝试
常见但无效的做法:
-
90% 失败
response.headers.set() is synchronous; adding await does not change the timing. The header is still set after the response is sent.
-
85% 失败
The response is already sent by the time the timeout executes, and headers cannot be modified after the fact. This also introduces race conditions.
-
80% 失败
Both set() and append() modify the same header object; the error is about timing, not the method used. The response is already sent.