主题
NextResponse
NextResponse 通过额外的便捷方法扩展了 网络响应 API。
¥NextResponse extends the Web Response API with additional convenience methods.
cookies
读取或更改响应的 Set-Cookie 标头。
¥Read or mutate the Set-Cookie header of the response.
set(name, value)
给定一个名称,在响应上设置一个具有给定值的 cookie。
¥Given a name, set a cookie with the given value on the response.
ts
// Given incoming request /home
let response = NextResponse.next()
// Set a cookie to hide the banner
response.cookies.set('show-banner', 'false')
// Response will have a `Set-Cookie:show-banner=false;path=/home` header
return responseget(name)
给定 cookie 名称,返回 cookie 的值。如果未找到 cookie,则返回 undefined。如果找到多个 cookie,则返回第一个。
¥Given a cookie name, return the value of the cookie. If the cookie is not found, undefined is returned. If multiple cookies are found, the first one is returned.
ts
// Given incoming request /home
let response = NextResponse.next()
// { name: 'show-banner', value: 'false', Path: '/home' }
response.cookies.get('show-banner')getAll()
给定 cookie 名称,返回 cookie 的值。如果未给出名称,则返回响应中的所有 cookie。
¥Given a cookie name, return the values of the cookie. If no name is given, return all cookies on the response.
ts
// Given incoming request /home
let response = NextResponse.next()
// [
// { name: 'experiments', value: 'new-pricing-page', Path: '/home' },
// { name: 'experiments', value: 'winter-launch', Path: '/home' },
// ]
response.cookies.getAll('experiments')
// Alternatively, get all cookies for the response
response.cookies.getAll()has(name)
给定一个 cookie 名称,如果响应中存在该 cookie,则返回 true。
¥Given a cookie name, return true if the cookie exists on the response.
ts
// Given incoming request /home
let response = NextResponse.next()
// Returns true if cookie exists, false if it does not
response.cookies.has('experiments')delete(name)
给定 cookie 名称,从响应中删除 cookie。
¥Given a cookie name, delete the cookie from the response.
ts
// Given incoming request /home
let response = NextResponse.next()
// Returns true for deleted, false if nothing is deleted
response.cookies.delete('experiments')json()
使用给定的 JSON 正文生成响应。
¥Produce a response with the given JSON body.
ts
import { NextResponse } from 'next/server'
export async function GET(request: Request) {
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 })
}redirect()
生成重定向到 URL 的响应。
¥Produce a response that redirects to a URL.
ts
import { NextResponse } from 'next/server'
return NextResponse.redirect(new URL('/new', request.url))在用于 NextResponse.redirect() 方法之前,可以创建和修改 URL。例如,你可以使用 request.nextUrl 属性获取当前 URL,然后修改它以重定向到不同的 URL。
¥The URL can be created and modified before being used in the NextResponse.redirect() method. For example, you can use the request.nextUrl property to get the current URL, and then modify it to redirect to a different URL.
ts
import { NextResponse } from 'next/server'
// Given an incoming request...
const loginUrl = new URL('/login', request.url)
// Add ?from=/incoming-url to the /login URL
loginUrl.searchParams.set('from', request.nextUrl.pathname)
// And redirect to the new URL
return NextResponse.redirect(loginUrl)rewrite()
生成一个重写(代理)给定 URL 的响应,同时保留原始 URL。
¥Produce a response that rewrites (proxies) the given URL while preserving the original URL.
ts
import { NextResponse } from 'next/server'
// Incoming request: /about, browser shows /about
// Rewritten request: /proxy, browser shows /about
return NextResponse.rewrite(new URL('/proxy', request.url))next()
next() 方法对代理非常有用,因为它允许你提前返回并继续路由。
¥The next() method is useful for Proxy, as it allows you to return early and continue routing.
ts
import { NextResponse } from 'next/server'
return NextResponse.next()你还可以使用 NextResponse.next({ request: { headers } }) 在生成响应时将 headers 转发到上游:
¥You can also forward headers upstream when producing the response, using NextResponse.next({ request: { headers } }):
ts
import { NextResponse } from 'next/server'
// Given an incoming request...
const newHeaders = new Headers(request.headers)
// Add a new header
newHeaders.set('x-version', '123')
// Forward the modified request headers upstream
return NextResponse.next({
request: {
// New request headers
headers: newHeaders,
},
})此操作会将 newHeaders 标志转发到目标页面、路由或服务器操作,而不会将其暴露给客户端。虽然这种模式对于向上游传递数据很有用,但应谨慎使用,因为包含这些数据的标头可能会被转发到外部服务。
¥This forwards newHeaders upstream to the target page, route, or server action, and does not expose them to the client. While this pattern is useful for passing data upstream, it should be used with caution because the headers containing this data may be forwarded to external services.
与之相反,NextResponse.next({ headers }) 是代理向客户端发送标头的简写形式。这不是最佳实践,应该避免使用。设置响应头(例如 Content-Type)可能会覆盖框架预期(例如服务器操作使用的 Content-Type),从而导致提交失败或流式响应损坏,这是造成此问题的原因之一。
¥In contrast, NextResponse.next({ headers }) is a shorthand for sending headers from proxy to the client. This is NOT good practice and should be avoided. Among other reasons because setting response headers like Content-Type, can override framework expectations (for example, the Content-Type used by Server Actions), leading to failed submissions or broken streaming responses.
ts
import { type NextRequest, NextResponse } from 'next/server'
async function proxy(request: NextRequest) {
const headers = await injectAuth(request.headers)
// DO NOT forward headers like this
return NextResponse.next({ headers })
}通常,应避免复制所有传入的请求标头,因为这样做可能会将敏感数据泄露给客户端或上游服务。
¥In general, avoid copying all incoming request headers because doing so can leak sensitive data to clients or upstream services.
建议采用防御性方法,使用允许列表创建传入请求头的子集。例如,你可以丢弃自定义的 x-* 标头,而只转发已知安全的标头:
¥Prefer a defensive approach by creating a subset of incoming request headers using an allow-list. For example, you might discard custom x-* headers and only forward known-safe headers:
ts
import { type NextRequest, NextResponse } from 'next/server'
function proxy(request: NextRequest) {
const incoming = new Headers(request.headers)
const forwarded = new Headers()
for (const [name, value] of incoming) {
const headerName = name.toLowerCase()
// Keep only known-safe headers, discard custom x-* and other sensitive ones
if (
!headerName.startsWith('x-') &&
headerName !== 'authorization' &&
headerName !== 'cookie'
) {
// Preserve original header name casing
forwarded.set(name, value)
}
}
return NextResponse.next({
request: {
headers: forwarded,
},
})
}