fix(nuxt): prevent duplicate `set-cookie` headers (#28211)

This commit is contained in:
Daniel Roe 2024-07-18 22:03:50 +01:00 committed by GitHub
parent 064e7b7f12
commit 58f4f47791
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 1 deletions

View File

@ -126,6 +126,16 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const writeFinalCookieValue = () => { const writeFinalCookieValue = () => {
if (opts.readonly || isEqual(cookie.value, cookies[name])) { return } if (opts.readonly || isEqual(cookie.value, cookies[name])) { return }
nuxtApp._cookies ||= {}
if (name in nuxtApp._cookies) {
// do not append a second `set-cookie` header
if (isEqual(cookie.value, nuxtApp._cookies[name])) { return }
// warn in dev mode
if (import.meta.dev) {
console.warn(`[nuxt] cookie \`${name}\` was previously set to \`${opts.encode(nuxtApp._cookies[name] as any)}\` and is being overridden to \`${opts.encode(cookie.value as any)}\`. This may cause unexpected issues.`)
}
}
nuxtApp._cookies[name] = cookie.value
writeServerCookie(useRequestEvent(nuxtApp)!, name, cookie.value, opts as CookieOptions<any>) writeServerCookie(useRequestEvent(nuxtApp)!, name, cookie.value, opts as CookieOptions<any>)
} }
const unhook = nuxtApp.hooks.hookOnce('app:rendered', writeFinalCookieValue) const unhook = nuxtApp.hooks.hookOnce('app:rendered', writeFinalCookieValue)

View File

@ -112,6 +112,8 @@ interface _NuxtApp {
[key: string]: unknown [key: string]: unknown
/** @internal */
_cookies?: Record<string, unknown>
/** @internal */ /** @internal */
_id?: number _id?: number
/** @internal */ /** @internal */

View File

@ -9,6 +9,8 @@ useCookie<string | null>('set-to-null-with-default', { default: () => 'default'
useCookie('browser-accessed-but-not-used') useCookie('browser-accessed-but-not-used')
useCookie('browser-accessed-with-default-value', { default: () => 'default' }) useCookie('browser-accessed-with-default-value', { default: () => 'default' })
useCookie('browser-set').value = 'set' useCookie('browser-set').value = 'set'
// confirm that it only sets one `set-cookie` header
useCookie('browser-set').value = 'set'
useCookie('browser-set-to-null').value = null useCookie('browser-set-to-null').value = null
useCookie<string | null>('browser-set-to-null-with-default', { default: () => 'default' }).value = null useCookie<string | null>('browser-set-to-null-with-default', { default: () => 'default' }).value = null
@ -17,7 +19,6 @@ const objectCookieSecond = useCookie('browser-object-default', {
default: () => ({ foo: 'bar' }), default: () => ({ foo: 'bar' }),
}) })
function changeCookie () { function changeCookie () {
console.log(objectCookie.value, objectCookieSecond.value)
if (objectCookie.value!.foo === 'baz') { if (objectCookie.value!.foo === 'baz') {
objectCookie.value!.foo = 'bar' objectCookie.value!.foo = 'bar'
} else { } else {