客户端Blob尺寸偶小于服务器发送文件,PDF无法显示问题求助
问题分析与修复方案
核心问题根源
服务器端文件写入逻辑缺陷:
writeFile函数存在拼写错误:filestream.on('finish')应为fileStream.on('finish'),导致文件写入完成的监听失效,可能文件未完全写入就触发后续的文件发送逻辑。- 未监听流的错误事件:如果文件流在写入过程中出错,Promise不会触发reject,后续代码仍会尝试发送不完整的文件。
- 以源流的
finish事件作为写入完成标志不准确,应该以目标写入流的close事件为准,确保文件完全落地到磁盘。
客户端资源处理逻辑错误:
- 用
Response对象直接创建ObjectURL,而非获取到的Blob文件对象,导致资源引用错误。 - 过早调用
revokeObjectURL,在PDF还未加载完成就回收了资源URL,导致文件无法正常显示。 - 代码逻辑顺序错误,非200状态时仍会执行资源URL创建逻辑,引发不必要的错误。
- 用
服务器端代码修复
修复writeFile函数
const fs = require('fs'); function writeFile(fileStream, fileName) { return new Promise(function (resolve, reject) { const file = fs.createWriteStream(fileName); // 监听写入流的错误 file.on('error', reject); // 监听源文件流的错误 fileStream.on('error', reject); fileStream.pipe(file); // 监听写入流的close事件,确保文件完全写入磁盘 file.on('close', () => { resolve(); }); }); }
修复文件发送与清理逻辑
writeFile(fileStream, params.file) .then(function() { ftps.end(); console.log(params.file); res.setHeader('Content-Type', 'application/pdf'); res.status(200).download(`./${params.file}`, params.file, (err) => { if (err) { console.error('文件发送失败:', err); return res.status(500).send({ message: "无法下载文件: " + err.message, }); } // 文件发送完成后删除临时文件 fs.unlink(`./${params.file}`, function (err) { if (err) { console.error('临时文件删除失败:', err); } else { console.log("临时文件已成功删除") } }); }); }) .catch(err => { // 处理文件写入失败的情况 console.error('文件写入失败:', err); ftps.end(); res.status(500).send({ message: "无法写入文件: " + err.message }); });
客户端代码修复
let toParse = await fetch(self.apiLink, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(self.params) }); l(toParse.status); if (toParse.status === 200) { let parsed; if (fileExpected) { parsed = await toParse.blob(); // 基于Blob创建有效资源URL const url = window.URL.createObjectURL(parsed); const $pdfFrame = $('#pdf_frame'); // 等待PDF加载完成后再回收URL $pdfFrame.on('load', function() { window.URL.revokeObjectURL(url); $pdfFrame.off('load'); // 移除监听避免重复触发 }); $pdfFrame.attr("src", url); } else { parsed = await toParse.json(); } hideLoader(); l(parsed); return parsed; } else { hideLoader(); console.error('请求失败,状态码:', toParse.status); }
内容的提问来源于stack exchange,提问作者Fumarja
相关产品推荐
相关产品推荐

