Svelte中如何使用相对URL发起API请求?
解决Svelte应用中动态发起API请求的相对URL问题
问题根源
Svelte Kit是同构框架,代码可能在服务器端(SSR/SSG)执行:
- 服务器环境中不存在
window对象,直接引用会触发ReferenceError - 框架重写了全局
fetch,服务器端调用时不支持相对URL(因为服务器无法感知当前前端域名)
而你需要的动态AJAX请求(用户交互触发)本应在浏览器执行,但如果代码逻辑不小心在服务器端被执行(比如组件初始化时的同步代码),就会触发报错。
解决方案
1. 确保代码仅在浏览器环境执行
方式一:使用onMount钩子
onMount是Svelte专属钩子,只会在浏览器端组件挂载后执行,此时可以安全使用浏览器原生API和相对URL:
<script> import { onMount } from 'svelte'; onMount(async () => { // 直接用相对URL,浏览器原生fetch会自动拼接当前域名 const response = await fetch('/foo'); const data = await response.json(); // 处理返回的数据 }); </script>
方式二:在事件处理函数中发起请求
用户交互(如点击按钮)触发的函数只会在浏览器环境执行,无需额外判断:
<script> async function handleFetchData() { const response = await fetch('/foo'); const data = await response.json(); // 处理返回的数据 } </script> <button on:click={handleFetchData}>获取数据</button>
方式三:用browser变量显式判断
导入Svelte Kit提供的browser变量,显式区分浏览器/服务器环境:
<script> import { browser } from '$app/environment'; async function fetchData() { if (browser) { const response = await fetch('/foo'); const data = await response.json(); // 处理返回的数据 } } </script>
2. 封装通用API请求工具
创建一个工具函数统一处理环境判断和请求逻辑,简化组件代码:
// src/lib/api.js import { browser } from '$app/environment'; export async function apiRequest(path, options = {}) { if (!browser) { throw new Error('API请求仅支持在浏览器环境发起'); } const response = await fetch(path, options); if (!response.ok) { throw new Error(`请求失败:${response.status}`); } return response.json(); }
组件中调用:
<script> import { apiRequest } from '$lib/api'; async function fetchData() { try { const data = await apiRequest('/foo'); // 处理返回的数据 } catch (error) { console.error('请求出错:', error); } } </script>
内容的提问来源于stack exchange,提问作者morpheus
相关产品推荐
相关产品推荐

