SvelteKit代理场景下load函数fetch请求如何省略URL中的主机地址
问题根源
你遇到的404问题本质是SvelteKit load 函数的运行环境差异导致的:
- 你在
svelte.config.js中配置的Vite代理,仅对客户端浏览器发起的请求生效 - 默认开启SSR的情况下,
load函数会先在Node服务端执行一次,此时调用的fetch是Node环境下的请求,不会走Vite开发服务器的代理规则,直接请求本地服务的/api/articles路径自然会返回404
能不能省略主机地址?
完全可以,只需要适配不同运行环境的请求逻辑即可,常见的三种解决方案如下:
方案1:按环境拼接请求前缀
通过环境变量和SSR标识区分请求地址,适配服务端/客户端不同场景:
- 在项目根目录的
.env文件新增两个环境变量:
# 客户端请求前缀,走Vite代理 VITE_API_CLIENT_BASE=/api # 服务端请求前缀,直接调用后端地址 VITE_API_SERVER_BASE=http://127.0.0.1:8000
- 调整
load函数的请求逻辑:
<script context="module"> export const load = async ({ fetch, ssr }) => { const baseUrl = ssr ? import.meta.env.VITE_API_SERVER_BASE : import.meta.env.VITE_API_CLIENT_BASE const res = await fetch(`${baseUrl}/articles`); // 后续业务逻辑 } </script>
方案2:关闭当前页面SSR
如果你的页面不需要服务端渲染,可以直接在页面组件顶部关闭SSR,此时load函数只会在客户端执行,相对路径请求会自动命中Vite代理:
<script context="module"> // 关闭当前页面服务端渲染 export const ssr = false; export const load = async ({ fetch }) => { // 直接写相对路径即可正常请求 const res = await fetch('/api/articles'); // 后续业务逻辑 } </script>
方案3:统一配置服务端请求转发
通过SvelteKit的hooks.server.js拦截服务端的/api前缀请求,统一转发到后端地址,这样不管是服务端还是客户端发起的请求,都可以直接用相对路径:
// src/hooks.server.js export async function handle({ event, resolve }) { if (event.url.pathname.startsWith('/api')) { // 转发请求到后端 return fetch(`http://127.0.0.1:8000${event.url.pathname.replace(/^\/api/, '')}`, { method: event.request.method, headers: event.request.headers, body: event.request.body }) } return resolve(event); }
内容的提问来源于stack exchange,提问作者MaxCore
相关产品推荐
相关产品推荐

