You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

客户端Blob尺寸偶小于服务器发送文件,PDF无法显示问题求助

问题分析与修复方案

核心问题根源

  1. 服务器端文件写入逻辑缺陷:

    • writeFile函数存在拼写错误:filestream.on('finish')应为fileStream.on('finish'),导致文件写入完成的监听失效,可能文件未完全写入就触发后续的文件发送逻辑。
    • 未监听流的错误事件:如果文件流在写入过程中出错,Promise不会触发reject,后续代码仍会尝试发送不完整的文件。
    • 以源流的finish事件作为写入完成标志不准确,应该以目标写入流的close事件为准,确保文件完全落地到磁盘。
  2. 客户端资源处理逻辑错误:

    • 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 15:06:26