You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不关闭SSR的情况下基于Store响应式变量触发Fetch请求?

无需关闭SSR的解决方案

问题根源

你之前的代码刷新崩溃主要有两个原因:

  1. SSR阶段Store无初始值:服务器端渲染时,dateStore/shiftStore可能未初始化,导致date或shift为undefined,调用toISOString()直接抛出错误。
  2. 服务器端fetch相对URL失效:原生fetch在服务器端无法解析相对URL(缺少浏览器环境的origin),导致请求失败。

正确实现步骤

1. 给Store设置初始有效值

确保Store在SSR和客户端都有可用的初始值,避免undefined报错:

// lib/store.js
import { writable } from 'svelte/store';

// 初始日期设为当前日期
const initialDate = new Date();
export const dateStore = writable(initialDate);

// 初始shift设为有效默认值(比如'1')
export const shiftStore = writable('1');

2. 修改+page.js的load函数(处理SSR初始数据)

使用SvelteKit提供的fetch参数(自动处理SSR的URL解析和代理),同时通过get方法获取Store初始值:

import { dateStore, shiftStore } from '../../../lib/store';
import { get } from 'svelte/store';

export const load = async ({ fetch }) => {
    const date = get(dateStore);
    const shift = get(shiftStore);
    const dateStr = date.toISOString().split('T')[0];

    // 获取初始评论数据
    const getComments = async () => {
        const res = await fetch(`/api/${dateStr}/${shift}/1`);
        return res.json();
    };

    // 获取初始区域数据
    const getAreas = async () => {
        const res = await fetch(`/api/api/TurnReportArea/1/${dateStr}/${shift}`);
        return res.json();
    };

    return {
        comments: getComments(),
        areas: getAreas()
    };
};

3. 修改+page.svelte(客户端响应Store变化)

通过browser变量限制仅在客户端执行响应Store变化的请求,避免SSR重复执行:

<script>
    import { dateStore, shiftStore } from '../../../lib/store';
    import { browser } from '$app/environment';

    // 接收load函数返回的SSR初始数据
    export let comments = [];
    export let areas = [];

    $: shift = $shiftStore;
    $: date = $dateStore;

    async function fetchComments(newDate, newShift) {
        const dateStr = newDate.toISOString().split('T')[0];
        const res = await fetch(`/api/${dateStr}/${newShift}/1`);
        comments = await res.json();
    }

    async function fetchAreas(newDate, newShift) {
        const dateStr = newDate.toISOString().split('T')[0];
        const res = await fetch(`/api/api/TurnReportArea/1/${dateStr}/${newShift}`);
        areas = await res.json();
    }

    // 仅在客户端,当date/shift变化时重新请求
    $: if (browser && date && shift) {
        fetchAreas(date, shift);
        fetchComments(date, shift);
    }
</script>

额外注意事项

  • 如果Store的初始值需要从服务器端获取(比如从请求头、Cookie),可以在hooks.server.js中初始化Store,确保SSR阶段能拿到正确值。
  • 不要在load函数中直接订阅Store,因为load只在页面初始加载时执行;客户端的响应式更新交给组件内的$:语句处理即可。

内容的提问来源于stack exchange,提问作者Avi4nFLu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:20:27