SvelteKit中如何调用带私钥API并向客户端传递数据?
SvelteKit客户端导入含私有环境变量模块报错的解决方案
问题原因
SvelteKit会追踪模块的依赖关系,只要某个文件导入了$env/static/private或$env/dynamic/private,整个文件就会被标记为服务器端专属模块,禁止在客户端代码(如+page.svelte、+page.ts)中导入。这和Next.js的树摇逻辑不同,SvelteKit是基于模块的导入来源判断是否允许客户端访问,哪怕你导出的变量本身不包含私有变量也会触发错误。
解决方案
1. 拆分服务器端与客户端模块
把需要使用私有环境变量的代码和客户端可访问的代码完全分离:
- 创建服务器端专属文件(比如放在
server/目录下,该目录下的文件默认仅在服务器运行):// server/test.server.ts import { AUTH_SECRET } from "$env/static/private"; // 这里编写依赖私钥的逻辑,比如调用需要认证的API export const fetchProtectedData = async () => { // 使用AUTH_SECRET完成认证等操作 const response = await fetch("https://your-protected-api.com/data", { headers: { Authorization: `Bearer ${AUTH_SECRET}` } }); return response.json(); }; - 创建客户端可访问的模块:
客户端直接导入// client/test.client.ts export const testValue = 1;testValue就不会触发错误。
2. 通过服务器端Load函数传递数据
如果需要在页面加载时获取依赖私钥的数据,使用+page.server.ts的load函数:
// src/routes/+page.server.ts import { AUTH_SECRET } from "$env/static/private"; import type { PageServerLoad } from "./$types"; export const load: PageServerLoad = async () => { // 在服务器端调用依赖私钥的API const protectedData = await fetch("https://your-protected-api.com/data", { headers: { Authorization: `Bearer ${AUTH_SECRET}` } }).then(res => res.json()); // 返回的数据会自动传递到客户端页面 return { protectedData }; };
在+page.svelte中接收数据:
<script lang="ts"> export let data; // 接收服务器返回的数据 console.log(data.protectedData); </script>
3. 使用服务器端API路由动态获取数据
如果需要在客户端交互后动态获取数据,创建服务器端API路由:
// src/routes/api/protected-data/+server.ts import { AUTH_SECRET } from "$env/static/private"; import type { RequestHandler } from "./$types"; export const GET: RequestHandler = async () => { const protectedData = await fetch("https://your-protected-api.com/data", { headers: { Authorization: `Bearer ${AUTH_SECRET}` } }).then(res => res.json()); return new Response(JSON.stringify(protectedData), { headers: { "Content-Type": "application/json" } }); };
客户端调用该API:
<script lang="ts"> let protectedData; async function loadData() { const response = await fetch("/api/protected-data"); protectedData = await response.json(); } // 页面加载时或用户交互时调用 loadData(); </script>
核心原则
所有依赖私有环境变量的代码必须完全在服务器端执行,客户端只能通过服务器端的load函数或API路由获取处理后的数据,不能直接导入包含私有变量的模块。
内容的提问来源于stack exchange,提问作者Jonathan Chang
相关产品推荐
相关产品推荐

