使用SvelteKit+Adapter-Cloudflare预渲染时,platform.env是否可用?
问题原因
预渲染(prerender = true)是在构建阶段执行的,此时代码运行在本地构建环境或Cloudflare的构建服务器中,而非Cloudflare的边缘运行时环境。platform.env是Cloudflare边缘运行时专属的对象,只有代码在边缘节点执行时才会存在,因此预渲染阶段无法获取该对象,自然也无法访问R2存储桶。
解决方案
根据业务需求,可选择以下几种方案:
方案1:构建阶段直接调用R2 API
如果页面必须预渲染,且需要在构建时就拿到R2数据,可以通过R2的官方API直接请求,绕过边缘运行时的限制。需提前在构建环境中配置R2的访问密钥(注意密钥安全,不要提交到代码仓库):
// +page.server.js import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3"; export const prerender = true; export async function load() { // 初始化R2客户端,使用构建环境变量中的密钥 const r2Client = new S3Client({ region: "auto", endpoint: `https://${process.env.CLOUDFLARE_ACCOUNT_ID}.r2.cloudflarestorage.com`, credentials: { accessKeyId: process.env.R2_ACCESS_KEY, secretAccessKey: process.env.R2_SECRET_KEY, }, }); // 调用R2 API获取数据 const command = new ListObjectsV2Command({ Bucket: process.env.R2_BUCKET_NAME }); const response = await r2Client.send(command); return { files: response.Contents }; }
方案2:用API路由代理R2请求
如果页面需要预渲染,但R2数据可在客户端加载后获取,可将访问R2的逻辑移到非预渲染的API路由中,再在页面客户端代码中请求该API:
第一步:创建非预渲染的API路由
// /api/r2-files/+server.js // 禁用预渲染,确保代码运行在Cloudflare边缘环境 export const prerender = false; export async function GET({ platform }) { const r2Bucket = platform.env.R2_BUCKET; const files = await r2Bucket.list(); return new Response(JSON.stringify(files), { headers: { 'Content-Type': 'application/json' } }); }
第二步:在预渲染页面中调用API
// +page.js import { browser } from '$app/environment'; export const prerender = true; export async function load({ fetch }) { let files = []; // 仅在浏览器环境中调用API,避免构建阶段请求失败 if (browser) { const res = await fetch('/api/r2-files'); files = await res.json(); } return { files }; }
方案3:调整预渲染策略
如果页面不需要强制预渲染,可改用prerender: 'auto'让SvelteKit自动判断是否预渲染,或直接对需要访问R2的页面禁用预渲染:
// +page.server.js // 自动判断是否预渲染,SvelteKit会跳过依赖运行时环境的页面 export const prerender = 'auto'; export async function load({ platform }) { const r2Bucket = platform.env.R2_BUCKET; // 正常处理R2相关逻辑 }
内容的提问来源于stack exchange,提问作者user21409596
相关产品推荐
相关产品推荐

