如何使用Node.js检测Amazon S3中的PDF文件是否可正常加载?
解决S3存储PDF无法加载的问题及批量检测方案
先修正你的下载代码
你当前代码里把data.Body转成utf-8字符串是错误的——PDF是二进制文件,强制转成文本编码会破坏原始数据,这也是你下载后无法打开的直接原因。正确的处理方式是保留二进制数据:
const s3 = new AWS.S3({ accessKeyId: AWSCredentials.accessKey, secretAccessKey: AWSCredentials.secret }); const downloadFile = async (bucketName, key) => { const params = { Bucket: bucketName, Key: key }; // 改用promise形式更易处理,避免回调嵌套 try { const data = await s3.getObject(params).promise(); // 直接保留二进制Buffer,不要转utf-8 return data.Body; // 这是Buffer类型,可直接写入文件或传给前端 } catch (err) { console.error('下载失败:', err); throw err; } }; // 示例:保存到本地验证 const fs = require('fs'); downloadFile('myBucket', 'mypdf.pdf').then(buffer => { fs.writeFileSync('./test.pdf', buffer); });
批量检测S3中PDF的有效性
如果要批量排查哪些PDF损坏,推荐用Mozilla官方的PDF解析库pdfjs-dist自动验证:
步骤1:安装依赖
npm install pdfjs-dist
步骤2:批量检测代码
const pdfjsLib = require('pdfjs-dist/legacy/build/pdf'); const fs = require('fs'); // 验证单个PDF Buffer是否有效 const isPdfValid = async (pdfBuffer) => { try { // 用PDFJS加载二进制数据 const pdf = await pdfjsLib.getDocument({ data: pdfBuffer }).promise; // 能成功获取页数,说明文件结构正常 await pdf.getPage(1); // 进一步验证第一页可加载 return true; } catch (err) { console.error('PDF无效:', err.message); return false; } }; // 遍历S3桶里的所有PDF文件并检测 const scanBucketPdfs = async (bucketName) => { const invalidFiles = []; let continuationToken = null; do { const listParams = { Bucket: bucketName, ContinuationToken: continuationToken, // 可添加前缀筛选特定目录下的PDF // Prefix: "docs/", Delimiter: '/' }; const listResponse = await s3.listObjectsV2(listParams).promise(); continuationToken = listResponse.NextContinuationToken; // 遍历每个文件 for (const obj of listResponse.Contents) { const key = obj.Key; // 只处理PDF后缀的文件 if (!key.toLowerCase().endsWith('.pdf')) continue; console.log('正在检测:', key); try { const data = await s3.getObject({ Bucket: bucketName, Key: key }).promise(); const isValid = await isPdfValid(data.Body); if (!isValid) { invalidFiles.push(key); } } catch (err) { console.error('处理文件失败', key, err.message); invalidFiles.push(key); } } } while (continuationToken); // 输出并保存结果 console.log('\n检测完成,无效PDF列表:'); invalidFiles.forEach(file => console.log('-', file)); fs.writeFileSync('./invalid-pdfs.txt', invalidFiles.join('\n')); }; // 执行检测 scanBucketPdfs('myBucket');
额外排查点
- 检查S3文件元数据:确认文件的
Content-Type是否为application/pdf。如果是text/plain或其他类型,浏览器可能会错误解析,但这不会导致文件损坏,只是标识问题。可通过S3控制台或批量修改元数据修复。 - 检查上传过程:如果是上传时的编码错误导致损坏,后续上传要确保用二进制模式上传,不要转成文本格式。
内容的提问来源于stack exchange,提问作者aaron
相关产品推荐
相关产品推荐

