From 58f4f47791907ed77c01e30f82625f8651ea509e Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Thu, 18 Jul 2024 22:03:50 +0100 Subject: [PATCH] fix(nuxt): prevent duplicate `set-cookie` headers (#28211) --- packages/nuxt/src/app/composables/cookie.ts | 10 ++++++++++ packages/nuxt/src/app/nuxt.ts | 2 ++ test/fixtures/basic/pages/cookies.vue | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/nuxt/src/app/composables/cookie.ts b/packages/nuxt/src/app/composables/cookie.ts index 45fab10d47..b26330b076 100644 --- a/packages/nuxt/src/app/composables/cookie.ts +++ b/packages/nuxt/src/app/composables/cookie.ts @@ -126,6 +126,16 @@ export function useCookie (name: string, _opts?: const nuxtApp = useNuxtApp() const writeFinalCookieValue = () => { 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) } const unhook = nuxtApp.hooks.hookOnce('app:rendered', writeFinalCookieValue) diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index fd8e33b3e6..c625e5b92b 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -112,6 +112,8 @@ interface _NuxtApp { [key: string]: unknown + /** @internal */ + _cookies?: Record /** @internal */ _id?: number /** @internal */ diff --git a/test/fixtures/basic/pages/cookies.vue b/test/fixtures/basic/pages/cookies.vue index 742b6824bc..b47ba29102 100644 --- a/test/fixtures/basic/pages/cookies.vue +++ b/test/fixtures/basic/pages/cookies.vue @@ -9,6 +9,8 @@ useCookie('set-to-null-with-default', { default: () => 'default' useCookie('browser-accessed-but-not-used') useCookie('browser-accessed-with-default-value', { default: () => 'default' }) 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-with-default', { default: () => 'default' }).value = null @@ -17,7 +19,6 @@ const objectCookieSecond = useCookie('browser-object-default', { default: () => ({ foo: 'bar' }), }) function changeCookie () { - console.log(objectCookie.value, objectCookieSecond.value) if (objectCookie.value!.foo === 'baz') { objectCookie.value!.foo = 'bar' } else {