AWS Lambda上传修改后PDF至S3,CDN预览乱码问题求助
问题分析与解决方案
问题根源
你遇到的乱码问题核心原因是上传到S3的不是二进制PDF数据,而是Base64编码的文本(甚至带data URI前缀):
pdfDoc.saveAsBase64({ dataUri: true })返回的是形如data:application/pdf;base64,JVBERi0xLjMK...的字符串,直接上传会导致S3存储的是文本内容,而非二进制PDF。- 即使去掉前缀,直接传递Base64字符串,AWS SDK不会自动解码为二进制,仍会以文本格式存储。
虽然本地下载后部分阅读器能自动识别并解码Base64,但CDN会按文本类型解析,因此显示乱码。
修复方案
推荐两种修复方式,优先选择方案一(更高效,无需Base64编解码开销):
方案一:直接使用二进制数据上传(推荐)
修改PDF修改函数,用pdf-lib的save()方法直接获取Uint8Array格式的二进制数据:
async function modificationFunction(opts) { const { fileData } = opts; const pdfDoc = await PDFDocument.load(fileData); // 执行你的修改操作(如画线等) const modifiedPDFData = await pdfDoc.save(); // 返回Uint8Array类型的二进制PDF数据 return modifiedPDFData; }
上传代码中,直接使用该二进制数据作为Body,并显式设置Content-Type(确保CDN和浏览器识别为PDF):
const params = { "Bucket": bucket_name, "Key": key, "Body": data, // 这里传入Uint8Array,SDK会自动处理为二进制上传 "ContentType": "application/pdf" // 必须显式设置,避免MIME类型错误 }; try { await s3.upload(params).promise(); console.log('File uploaded:', `s3://${bucket_name}/${key}`); } catch (err) { console.error('Upload failed:', err); throw err; }
方案二:解码Base64后上传(兼容原有逻辑)
如果你需要保留Base64相关逻辑,需先去掉data URI前缀并解码为二进制Buffer:
async function modificationFunction(opts) { const { fileData } = opts; const pdfDoc = await PDFDocument.load(fileData); // 执行你的修改操作 // 方式1:获取纯Base64字符串(不带data URI前缀) const modifiedBase64 = await pdfDoc.saveAsBase64(); // 方式2:如果已带前缀,拆分取出Base64部分 // const modifiedBase64Full = await pdfDoc.saveAsBase64({ dataUri: true }); // const modifiedBase64 = modifiedBase64Full.split(',')[1]; const modifiedPDFData = Buffer.from(modifiedBase64, 'base64'); // 解码为Buffer return modifiedPDFData; }
上传代码同样使用上述Buffer作为Body,并添加ContentType: "application/pdf"参数即可。
额外注意事项
- 始终显式设置
ContentType:S3默认会根据文件扩展名推断,但手动设置能避免推断错误,确保CDN正确返回Content-Type响应头。 - 下载代码无需修改:
s3.getObject返回的data.Body是Uint8Array,完全兼容pdf-lib的load()方法。
内容的提问来源于stack exchange,提问作者Debadatta Meher
相关产品推荐
相关产品推荐

