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

如何在SvelteKit+静态适配器中缓存Strapi API获取的图片?

解决方案:在SvelteKit中缓存Strapi图片并静态生成站点

方法一:构建前自定义脚本批量下载图片

直接编写Node.js脚本,在SvelteKit构建前从Strapi拉取所有媒体资源,保存到项目static目录,同时替换API返回内容里的图片链接为本地路径。

步骤:

  1. 在项目根目录新建scripts/download-strapi-images.js脚本:
import fs from 'fs/promises';
import path from 'path';
import fetch from 'node-fetch';

const STRAPI_API_URL = 'https://your-strapi-instance.com/api';
const IMAGE_DEST_DIR = path.join(process.cwd(), 'static', 'strapi-images');

async function downloadImage(url, filename) {
  const res = await fetch(url);
  const buffer = await res.buffer();
  await fs.mkdir(IMAGE_DEST_DIR, { recursive: true });
  await fs.writeFile(path.join(IMAGE_DEST_DIR, filename), buffer);
}

async function fetchAndProcessContent() {
  // 拉取作品集条目等目标内容
  const contentRes = await fetch(`${STRAPI_API_URL}/portfolio-items?populate=*`);
  const contentData = await contentRes.json();

  // 遍历下载图片并替换链接
  for (const item of contentData.data) {
    if (item.attributes.image) {
      const strapiImageUrl = item.attributes.image.data.attributes.url;
      const imageFilename = strapiImageUrl.split('/').pop();
      // 拼接完整Strapi图片地址(去掉API路径前缀)
      await downloadImage(`${STRAPI_API_URL.replace('/api', '')}${strapiImageUrl}`, imageFilename);
      // 替换为本地静态资源路径
      item.attributes.image.data.attributes.url = `/strapi-images/${imageFilename}`;
    }
  }

  // 把处理后的内容存为本地JSON,供页面加载
  await fs.writeFile(path.join(process.cwd(), 'src', 'data', 'portfolio.json'), JSON.stringify(contentData));
}

fetchAndProcessContent().catch(err => console.error(err));
  1. 在package.json的scripts中添加构建前置命令:
{
  "scripts": {
    "prebuild": "node scripts/download-strapi-images.js",
    "build": "vite build"
  }
}
  1. 页面中直接读取本地JSON文件加载内容,预渲染时生成的HTML会自动使用本地图片链接。

方法二:预渲染时动态下载图片(适配SvelteKit prerender)

利用SvelteKit的预渲染机制,在页面/布局的load函数中抓取Strapi内容,同时下载图片到static目录,返回修改后的链接给页面组件。

  1. 先在src/routes/+layout.js中开启预渲染:
export const prerender = true;
export const ssr = true;
  1. 在页面的+page.server.js中处理图片下载与链接替换:
import fs from 'fs/promises';
import path from 'path';
import fetch from 'node-fetch';

const STRAPI_API_URL = 'https://your-strapi-instance.com/api';
const IMAGE_DEST_DIR = path.join(process.cwd(), 'static', 'strapi-images');

export async function load() {
  const contentRes = await fetch(`${STRAPI_API_URL}/portfolio-items?populate=*`);
  const contentData = await contentRes.json();

  for (const item of contentData.data) {
    if (item.attributes.image) {
      const strapiImagePath = item.attributes.image.data.attributes.url;
      const imageUrl = `${STRAPI_API_URL.replace('/api', '')}${strapiImagePath}`;
      const imageFilename = strapiImagePath.split('/').pop();
      const localPath = path.join(IMAGE_DEST_DIR, imageFilename);

      // 检查是否已下载,避免重复请求
      try {
        await fs.access(localPath);
      } catch {
        const res = await fetch(imageUrl);
        const buffer = await res.buffer();
        await fs.mkdir(IMAGE_DEST_DIR, { recursive: true });
        await fs.writeFile(localPath, buffer);
      }

      // 替换为本地相对链接
      item.attributes.image.data.attributes.url = `/strapi-images/${imageFilename}`;
    }
  }

  return {
    portfolioItems: contentData.data
  };
}

预渲染时SvelteKit会执行load函数下载图片,生成的静态HTML里的图片链接会指向本地static目录,构建完成后无需Strapi运行即可正常展示。

注意事项

  • 确保Strapi媒体文件公开可访问,若需权限,要在请求中携带API Token。
  • 可以用图片ID或哈希值作为文件名,避免重名覆盖。
  • Strapi内容更新后,需重新执行构建流程同步新内容与图片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 12:21:16