AWS S3结合express-fileupload实现图片与PDF上传的配置问题
解决方案
你要做的调整不只是新增PDF对应的Content-Type,还要修改现有代码里硬编码的类型限制逻辑,具体调整如下:
1. 现有代码的核心限制点
当前代码有两处规则强制只能上传图片:
buildObject函数中的ContentType被硬编码为image/jpeg,不会随传入的文件类型动态变化upload函数的判断逻辑if (fileData.includes("base64") || !options.type) type = "image/jpeg",只要是base64格式的文件就强制覆盖为图片类型,PDF的base64数据也会被误判
2. 代码修改步骤
- 改造
buildObject函数,新增contentType参数,替换硬编码的固定图片类型 - 调整
upload函数的类型判断逻辑,允许传入PDF对应的application/pdf类型,仅在未指定类型的场景下才默认赋值为图片类型 - 可选新增文件类型白名单校验,避免非法文件上传
修改后的参考代码
import AWS from "aws-sdk"; const s3 = new AWS.S3({ accessKeyId: process.env.S3_ACCESS_KEY, secretAccessKey: process.env.S3_SECRET_KEY, }); // 新增contentType动态参数 const buildObject = (key: string, body: string, contentType: string) => { return { Bucket: process.env.S3_BUCKET_NAME, Key: `${key}`, Body: body, ACL: "public-read", ContentEncoding: "base64", ContentType: contentType, }; }; // 配置允许的文件类型白名单,可按需扩展 const ALLOWED_TYPES = ["image/jpeg", "image/png", "application/pdf"]; export const upload = (fileData: string, options = { type: null }) => { let { type = "image/png" } = options; // 先校验传入的类型是否合法 if (!ALLOWED_TYPES.includes(type)) { throw new Error("不支持的文件类型"); } // 仅在未传type时才用默认的jpeg类型,不要覆盖合法的传入类型 if (!options.type) type = "image/jpeg"; const fileExt = type.split("/")[1]; const file = `${new Date().getTime()}.${fileExt}`; // 把动态类型传入buildObject const object = buildObject(file, fileData, type); return new Promise((resolve, reject) => { s3.upload(object, (err, data) => { if (err) reject(err); else resolve(data.Location); }); }); };
3. 额外注意事项
- 如果你的S3桶配置了桶策略限制了允许上传的文件类型,需要在策略中新增
application/pdf类型的允许规则 - 如果需要在前端直接预览PDF,确认S3的CORS配置没有限制
application/pdf类型的跨域访问即可,不需要其他额外配置
内容的提问来源于stack exchange,提问作者VicWentBananas
相关产品推荐
相关产品推荐

