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

前端预览后端PDF文件问题:Nest+React实现遇阻

前端预览后端存储PDF文件的问题解决(NestJS + React)

问题背景

需要在前端预览(而非下载)NestJS后端服务器存储的PDF文件,现有后端控制器和React请求代码,但尝试多种方案后出现以下问题:

  • 设置responseType为application/pdf:Postman可正常获取,但React端打开空白页
  • 设置responseType为blob:出现TypeScript类型错误,提示无法对该类型调用createObjectURL
  • 后端流式传输文件:前端无任何响应

后端(NestJS)代码修正

原控制器存在核心问题:错误设置Content-Type为arraybuffer,未指定Content-Disposition告知浏览器预览文件。修正后的代码如下:

import { Response } from 'express';
import * as path from 'path';

@Get(':id')
async seeUploadedFile(
  @Param('id') id: number,
  @Res() res: Response,
) {
  const document = await this.service.getDocument(id);
  // 明确指定PDF的Content-Type
  res.setHeader('Content-Type', 'application/pdf');
  // 设置inline参数,强制浏览器预览而非下载文件
  res.setHeader(
    'Content-Disposition',
    `inline; filename="${path.basename(document.path)}"`
  );
  // sendFile会自动处理文件流式传输,无需手动实现流逻辑
  return res.sendFile(document.path, { root: '.' });
}

关键修正点

  1. 使用await替代then,避免回调嵌套,提升代码可读性
  2. 设置Content-Disposition: inline:这是让浏览器预览文件的核心头信息,若设为attachment则会触发下载
  3. 正确设置Content-Type为application/pdf,而非arraybuffer

前端(React + TypeScript)代码修正

原请求未正确设置responseType,且缺少错误处理和URL资源释放逻辑。修正后的代码如下:

const handleVisu = async (idDocument: number) => {
  try {
    const response = await client.get('/documents/' + idDocument, {
      headers: { "Authorization": "Bearer " + loginToken },
      // 明确指定responseType为blob,解决数据解析问题
      responseType: 'blob'
    });
    const blobFile = new Blob([response.data], { type: 'application/pdf' });
    const blobFileURL = URL.createObjectURL(blobFile);
    const previewWindow = window.open(blobFileURL);
    
    // 窗口关闭时释放Blob URL,避免内存泄漏
    if (previewWindow) {
      previewWindow.addEventListener('beforeunload', () => {
        URL.revokeObjectURL(blobFileURL);
      });
    }
  } catch (error) {
    console.error('文件预览失败:', error);
    // 可添加用户友好的错误提示,比如弹窗告知预览失败
  }
};

关键修正点

  1. 设置responseType: 'blob':axios会将响应数据解析为Blob对象,直接用于创建预览URL
  2. 解决TypeScript类型错误:axios的类型定义已支持blob作为responseType选项,若仍报错可添加类型断言responseType: 'blob' as const
  3. 添加URL.revokeObjectURL:在预览窗口关闭时释放Blob URL,防止内存泄漏
  4. 用async/await替代链式then,配合try/catch统一处理错误

原方案问题分析

  1. responseType设为application/pdf:axios不支持该响应类型,正确的二进制类型应为blob或arraybuffer,错误的类型导致前端无法解析数据,出现空白页
  2. responseType设为blob出现类型错误:多为TypeScript类型推断问题,明确指定responseType: 'blob'即可解决
  3. 后端流式传输无响应:手动实现流式传输易出现响应未正确结束、头信息设置错误等问题,NestJS的res.sendFile已封装了可靠的流式传输逻辑,无需重复造轮子

内容的提问来源于stack exchange,提问作者Thibault Muller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:00:47