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

SvelteKit如何在Store中调用+server.ts接口获取服务器列表?

Svelte Store调用+server.ts接口的错误修复方案

问题背景

在Svelte项目中,尝试通过Store调用src/routes/api/+server.ts接口获取服务器列表并展示时,出现两个错误:

  • Failed to parse URL from /api(URL解析失败)
  • Cannot read properties of undefined (reading 'length')(读取未定义属性length)

错误原因及修复步骤

1. 解决Failed to parse URL from /api错误

原因:代码在服务端渲染(SSR)阶段执行时,相对路径/api缺少base URL上下文,导致fetch无法解析正确的URL;且Store中的fetchServers可能在服务端被执行,服务端环境没有浏览器的URL上下文支撑。

修复方案(二选一即可):

方案A:传入SvelteKit提供的fetch函数

  • 修改serverSection.svelte,将组件获取到的SvelteKit专属fetch传给Store方法:
<script lang="ts">
  export let bgImage: string
  export let logo: string
  export let text: string

  import { fetchServers, serversStore } from '../stores/servers'
  import Server from './server.svelte'
  import { page } from '$app/stores'

  fetchServers($page.fetch)
</script>
  • 修改servers.ts,接收外部传入的fetch函数:
import { writable, type Writable } from 'svelte/store'

export const serversStore: Writable<any[]> = writable([])

export const fetchServers = async (fetchFn = fetch) => {
  const response = await fetchFn('/api', {
    method: 'GET',
    headers: {
      'content-type': 'application/json',
      accept: 'application/json',
    },
  })
  const data = await response.json()
  serversStore.set(data)
}

方案B:确保仅在客户端执行fetch

利用Svelte的onMount钩子,限制fetchServers仅在浏览器环境运行:

<script lang="ts">
  export let bgImage: string
  export let logo: string
  export let text: string

  import { fetchServers, serversStore } from '../stores/servers'
  import Server from './server.svelte'
  import { onMount } from 'svelte'

  onMount(() => {
    fetchServers()
  })
</script>

2. 解决Cannot read properties of undefined (reading 'length')错误

原因:

  • serversStore初始值为undefined(writable()未传初始值),组件遍历数据时会读取undefined的length属性;
  • fetchServers中直接将Response对象存入Store,而非接口返回的JSON数组,Response对象本身没有length属性。

修复方案:

  • 修改servers.ts,设置初始空数组并解析响应为JSON:
import { writable, type Writable } from 'svelte/store'

// 初始化为空数组,避免undefined报错
export const serversStore: Writable<any[]> = writable([])

export const fetchServers = async (fetchFn = fetch) => {
  try {
    const response = await fetchFn('/api', {
      method: 'GET',
      headers: {
        'content-type': 'application/json',
        accept: 'application/json',
      },
    })

    if (!response.ok) {
      throw new Error(`请求失败: ${response.status}`)
    }

    // 解析响应为JSON数组
    const serverData = await response.json()
    serversStore.set(serverData)
  } catch (error) {
    console.error('获取服务器列表失败:', error)
    serversStore.set([]) // 出错时设置空数组,避免组件报错
  }
}
  • 组件中遍历数据时,直接使用each即可(因初始值为空数组,不会触发length读取错误):
<!-- serverSection.svelte 中的HTML部分 -->
<div>
  {#each $serversStore as server}
    <Server {...server} />
  {/each}
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:20:31