Vue3.js(Replit部署)中使用Promise从AWS获取图片时出现TypeError: At.STS is undefined错误
嘿,这个问题我之前在前端用AWS SDK v2的时候也踩过坑!TypeError: At.STS is undefined本质上是因为AWS SDK v2原本是为Node.js环境设计的,直接在Vue前端项目中使用(尤其是部署打包后),很容易出现模块缺失的情况——STS模块要么在打包时被树摇工具误删,要么浏览器环境下没能正确加载到这个依赖。
结合你在Replit部署的场景,我给你几个靠谱的解决思路,按优先级推荐:
1. 升级到AWS SDK for JavaScript v3(最推荐)
AWS SDK v3是模块化的,专门优化了前端使用体验,体积更小,也从根源上避免了这种模块缺失的问题。具体操作如下:
第一步:安装v3依赖
在Replit的终端里执行:
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
第二步:修改GetImageFunc.js代码
把原来基于v2的S3初始化和签名URL生成逻辑换成v3的写法:
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import Getawsapi from "@/services/getawsapi.service"; export const func = { get_image: async (data) => { const myBucket = 'mybucket'; const myKey = data; const signedUrlExpireSeconds = 3600 * 1; try { const awsData = await Getawsapi.getAWS2(); const accessKeyId = awsData.AWS_ACCESS_KEY; const secretAccessKey = awsData.AWS_SECRET_KEY; // 用v3的S3Client初始化客户端 const s3Client = new S3Client({ region: 'eu-north-1', credentials: { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey } }); // 创建GetObject命令 const getObjectCommand = new GetObjectCommand({ Bucket: myBucket, Key: myKey }); // 生成签名URL const url = await getSignedUrl(s3Client, getObjectCommand, { expiresIn: signedUrlExpireSeconds }); return url; } catch (error) { console.error("Error generating signed URL:", error); throw error; } } };
这个方法能彻底解决模块缺失的问题,因为v3是按需加载模块的,打包时只会包含你用到的S3Client和签名相关的代码,Replit的Vite打包工具也能完美处理这些模块。
2. 如果你坚持用AWS SDK v2的临时解决方案
如果不想升级v3,你需要确保打包时STS模块被正确包含。可以尝试在Vue的配置文件(比如vite.config.js或者vue.config.js,看Replit用的是哪个构建工具)里添加polyfill或者指定保留STS模块:
比如Vite的话,先安装依赖:
npm install rollup-plugin-polyfill-node --save-dev
然后修改vite.config.js:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import nodePolyfills from 'rollup-plugin-polyfill-node' export default defineConfig({ plugins: [ vue(), nodePolyfills({ include: ['node_modules/aws-sdk/**/*'], http: true, https: true, stream: true, crypto: true }) ] })
不过这个方法比较折腾,而且v2的体积大,前端加载慢,还是更推荐直接升级到v3。
额外的优化建议(和当前错误无关,但能提升体验)
你在获取图片URL的时候用了forEach(async (item) => {}),这里的async/await其实不会等待所有请求完成,因为forEach不支持异步函数。可以改成用Promise.all来确保所有图片URL都获取后再更新视图:
// 替换原来的forEach逻辑 const imageFetchPromises = this.result_list.map(async (item) => { if (item.image) { item.imageUrl = await this.get_image(item.id, item.image); } return item; }); await Promise.all(imageFetchPromises);
这样能避免视图更新时部分图片URL还没获取到的情况。
最后提个安全小提醒:你现在是从后端获取AWS密钥,一定要确保这些密钥的权限是最小化的——只能访问指定的S3桶和对象,并且设置了合理的过期时间,避免密钥泄露带来的安全风险。
备注:内容来源于stack exchange,提问作者user12288003

