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

如何使用AccessKeyId和SecretAccessKey在浏览器中访问AWS S3存储桶文件?

实现S3视频在React前端播放的完整步骤

1. 前置S3存储桶配置

绝对不要将AccessKeyId、SecretAccessKey硬编码到前端代码中,会直接导致密钥泄露、资产被盗刷

  • 配置S3桶CORS规则,允许前端域名跨域访问,示例配置如下:
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET"],
    "AllowedOrigins": ["https://你的前端域名.com", "http://localhost:3000"], // 开发环境可加localhost
    "ExposeHeaders": ["ETag", "Content-Length", "Content-Range"],
    "MaxAgeSeconds": 3600
  }
]
  • 给AccessKeyId绑定的IAM用户配置最小权限,仅开放s3:GetObject权限即可,无需额外权限。
  • 不要开启存储桶公共访问权限,所有视频访问通过后端生成的预签名URL实现。

2. NestJS后端实现(生成预签名播放URL)

2.1 安装依赖

npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner

2.2 编写S3服务

在Nest项目中新增S3服务,通过环境变量读取AWS配置(不要硬编码密钥):

import { Injectable } from '@nestjs/common';
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';

@Injectable()
export class S3Service {
  private s3Client: S3Client;
  constructor() {
    this.s3Client = new S3Client({
      region: process.env.AWS_REGION,
      credentials: {
        accessKeyId: process.env.AWS_ACCESS_KEY_ID,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
      },
    });
  }

  async getVideoPlayUrl(fileName: string, expiresIn = 3600) {
    const command = new GetObjectCommand({
      Bucket: process.env.AWS_S3_BUCKET_NAME,
      Key: fileName,
    });
    // 生成有效期默认为1小时的预签名URL
    return getSignedUrl(this.s3Client, command, { expiresIn });
  }
}

2.3 提供对外接口

编写Controller对外暴露获取播放地址的接口,可自行添加权限校验逻辑:

import { Controller, Get, Query } from '@nestjs/common';
import { S3Service } from './s3.service';

@Controller('video')
export class VideoController {
  constructor(private readonly s3Service: S3Service) {}

  @Get('play-url')
  async getPlayUrl(@Query('fileName') fileName: string) {
    // 此处可添加权限校验,比如判断当前登录用户是否有权限访问该视频
    const url = await this.s3Service.getVideoPlayUrl(fileName);
    return { playUrl: url };
  }
}

3. React前端实现视频播放

你可以直接用原生HTML5 video标签,也可以用第三方播放器如react-player适配更多场景:

3.1 原生video标签实现示例

import { useEffect, useState } from 'react';

const VideoPlayer = ({ fileName }: { fileName: string }) => {
  const [playUrl, setPlayUrl] = useState('');

  useEffect(() => {
    // 调用后端接口获取预签名URL
    fetch(`/api/video/play-url?fileName=${encodeURIComponent(fileName)}`)
      .then(res => res.json())
      .then(data => setPlayUrl(data.playUrl));
  }, [fileName]);

  if (!playUrl) return <div>加载中...</div>;

  return (
    <video 
      src={playUrl} 
      controls 
      width="100%" 
      preload="metadata"
    />
  );
};

export default VideoPlayer;

3.2 react-player实现示例

如果需要支持更多格式、自定义播放控件,可以安装react-player:

npm install react-player

对应组件代码:

import ReactPlayer from 'react-player';
// 其他逻辑和原生实现一致,替换渲染部分即可
return <ReactPlayer url={playUrl} controls width="100%" />;

常见问题排查

  • 跨域报错:检查S3 CORS规则中的AllowedOrigins是否包含当前前端域名,是否允许GET请求
  • 视频无法加载:检查预签名URL是否过期,IAM用户是否有对应文件的GetObject权限,文件名是否正确
  • 进度条拖动失效:检查CORS规则是否暴露了Content-Range响应头,S3是否正常响应range请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:06:05