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

浏览器端AWS SDK访问Wasabi S3时SharedIniFileCredentials报错解决

问题根因

SharedIniFileCredentials是AWS SDK为Node.js服务端环境设计的专属凭证类,依赖Node.js原生fs文件系统模块读取本地~/.aws/credentials配置文件,浏览器环境无本地文件系统访问权限,webpack打包前端资源时会直接剔除该Node专属模块,因此会抛出「is not a constructor」错误。
除此之外你的实现存在致命安全风险:禁止在前端浏览器代码中写入S3/ Wasabi永久访问密钥,前端代码对用户完全公开,任何人打开开发者工具就能拿到密钥,可随意操作存储桶资源、产生高额账单。

推荐解决方案(无安全风险,适配Next.js特性)

不要在前端直接调用S3 SDK,借助Next.js的服务端能力做资源代理,S3交互逻辑全部放在服务端执行,密钥全程不暴露给前端,你原有Node.js环境下的S3逻辑几乎可以直接复用。

  1. 新建Next.js服务端接口处理Wasabi资源请求
    如果使用Pages Router,在pages/api目录下新建接口文件:
// pages/api/wasabi-asset/[...key].js
import AWS from 'aws-sdk';

// 该段代码仅在服务端运行,环境变量不会打包进前端代码
const s3 = new AWS.S3({
  accessKeyId: process.env.NX_WASABI_KEY,
  secretAccessKey: process.env.NX_WASABI_SECRET,
  region: process.env.NX_WASABI_REGION,
  endpoint: new AWS.Endpoint(process.env.NX_WASABI_ENDPOINT),
  s3ForcePathStyle: true
});

export default async function handler(req, res) {
  // 拼接文件key,支持多级路径
  const fileKey = Array.isArray(req.query.key) ? req.query.key.join('/') : req.query.key;
  try {
    const objectData = await s3.getObject({
      Bucket: process.env.NX_WASABI_BUCKET,
      Key: fileKey
    }).promise();

    // 设置正确的资源类型与缓存头
    res.setHeader('Content-Type', objectData.ContentType || 'image/jpeg');
    res.setHeader('Cache-Control', 'public, max-age=86400');
    res.send(objectData.Body);
  } catch (err) {
    res.status(404).send('资源不存在');
  }
}

如果使用App Router,可在app/api目录下新建对应的Route Handler,逻辑完全一致。

  1. 简化前端组件代码
    不需要手动拉取Buffer转base64,直接将图片地址指向你自建的服务端接口即可,性能更好、代码更简洁:
import Image from 'next/image';
import styles from './PaletteImage.module.scss';

interface Props {
  name: string;
  source: string;
}

const PaletteImage = ({ name, source }: Props) => {
  return (
    <div className={styles.imageContainer}>
      <Image
        alt={name}
        layout="fill"
        objectFit="contain"
        objectPosition="left top"
        src={`/api/wasabi-asset/${encodeURIComponent(source)}`}
      />
    </div>
  );
};

export default PaletteImage;
不推荐方案(仅特殊场景使用)

如果因业务需求必须在前端直连Wasabi,必须满足以下前提:

  • 完全删除SharedIniFileCredentials相关代码,该类无法在浏览器环境运行
  • 禁止使用永久访问密钥,必须通过服务端调用STS生成有效期不超过15分钟的临时凭证,且临时凭证仅绑定对应资源的只读权限
  • 前端初始化S3客户端时直接传入临时凭证:
import AWS from 'aws-sdk';
// 注意:前端可读取的环境变量需要按框架要求添加公共前缀(Next.js为NEXT_PUBLIC_,NX为NX_PUBLIC_)
const s3 = new AWS.S3({
  accessKeyId: 临时凭证.accessKeyId,
  secretAccessKey: 临时凭证.secretAccessKey,
  sessionToken: 临时凭证.sessionToken, // 临时凭证必须传该参数
  region: process.env.NEXT_PUBLIC_WASABI_REGION,
  endpoint: process.env.NEXT_PUBLIC_WASABI_ENDPOINT,
  s3ForcePathStyle: true,
  signatureVersion: 'v4'
});

补充说明:你原有Node.js代码中先实例化SharedIniFileCredentials再手动赋值密钥的写法完全冗余,Node.js环境下也可以直接将密钥传入S3构造函数,不需要依赖本地ini配置文件。


内容的提问来源于stack exchange,提问作者Miha Šušteršič

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:27:24