No meu site SvelteKit eu faço uma solicitação ao meu backend dentro da LayoutServerLoad
função, em formato +layout.server.ts
. Ou seja, quando o site é aberto com um ?affiliate_id=bla
parâmetro de consulta, quero enviar isso para o backend:
import type { LayoutServerLoad } from "./$types";
import { keyBy } from "$lib/utils";
import { backendUrl } from "$lib/config";
export const trailingSlash = "always";
export const load: LayoutServerLoad = async ({ locals, url, fetch }) => {
const affiliate_id = url.searchParams.get("affiliate_id");
if (affiliate_id) {
const headers = {
"Content-Type": "application/json",
"X-CSRFToken": locals.csrfToken,
};
fetch(`${backendUrl}/shop/basket/`, { method: "POST", credentials: "include", headers, body: JSON.stringify({ affiliate_id }) })
.catch(error => {
console.error("Error storing affiliate_id: ", error);
});
}
return {
// I'm returning a bunch of data here
};
};
O problema é que a resposta do backend contém um set-cookie
cabeçalho e o cookie não está sendo armazenado no navegador.
Quando mudo minha load
função para apenas retornar affiliate_id
:
export const load: LayoutServerLoad = async ({ locals, url }) => {
return {
affiliateId: url.searchParams.get("affiliate_id"),
// and more data
};
};
E então faça a solicitação dentro de +layout.svelte
, então tudo funcionará bem.
<script lang="ts">
import type { PageData } from "./$types";
import { onMount } from "svelte";
export let data: PageData;
const { affiliateId } = data;
onMount(async () => {
if (affiliateId) {
// Do the request here
}
});
</script>
<slot />
Agora o cookie da resposta está armazenado perfeitamente no navegador.
Por que o cookie não é armazenado ao fazer a mesma solicitação na load
função?
As solicitações em uma função de carregamento do servidor são feitas pelo servidor e não pelo navegador do cliente; o cliente não receberá nenhum cookie por padrão (embora exista alguma lógica que encaminhe cookies ao fazer a solicitação).
O objeto de evento da função de carregamento do servidor possui uma
cookies
propriedade que pode ser usada para encaminhar cookies. Isso pode ser um pouco indireto, pois o cabeçalho retornado deve ser analisado primeiro (você recebe um erro ao tentar definir umSet-Cookie
cabeçalho diretamente).