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

如何使用ngx-extended-pdf-viewer在Angular中显示Blob格式PDF?绑定src属性无效问题排查

解决ngx-extended-pdf-viewer绑定Blob无法显示PDF的问题

我之前也碰到过类似的情况,帮你梳理几个可能的问题点和解决办法:

1. 先确认服务端返回的Blob格式是否正确

很多时候服务端返回的是ArrayBuffer而非直接的Blob,或者返回的Blob没有正确标记MIME类型。你可以先修改getDocPreview方法,确保数据被正确转换为PDF类型的Blob:

import { pdfDefaultOptions } from 'ngx-extended-pdf-viewer';
import { OnDestroy } from '@angular/core';

export class YourComponent implements OnDestroy {
  pdfToPreview?: Blob;
  pdfObjectUrl?: string; // 新增变量存储Object URL,稳定性更好

  getDocPreview() { 
    this.myService.getDocPreview().subscribe({
      next: (data) => {
        // 处理服务端返回的数据:如果是ArrayBuffer,转成Blob并指定PDF类型
        if (data instanceof ArrayBuffer) {
          this.pdfToPreview = new Blob([data], { type: 'application/pdf' });
        } else if (data instanceof Blob) {
          // 确保Blob的MIME类型是PDF,避免类型不正确导致无法识别
          this.pdfToPreview = data.type === 'application/pdf' 
            ? data 
            : new Blob([data], { type: 'application/pdf' });
        }
        // 生成Object URL替代直接绑定Blob,兼容性和稳定性更佳
        this.pdfObjectUrl = URL.createObjectURL(this.pdfToPreview);
      },
      error: (err) => {
        console.error('获取PDF文件失败:', err);
      }
    });
  }

  // 组件销毁时释放Object URL,防止内存泄漏
  ngOnDestroy(): void {
    if (this.pdfObjectUrl) {
      URL.revokeObjectURL(this.pdfObjectUrl);
    }
  }
}

2. 修改HTML模板,绑定Object URL

虽然官方文档说支持直接绑定Blob,但实际项目中绑定Object URL的表现更稳定。同时调整模态框的显示逻辑:

<button (click)="getDocPreview()"> viewer </button>
<!-- 移除直接触发模态框的属性,改为代码控制时机 -->
<div class="modal fade" id="provaPdfStaticModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel2" aria-hidden="true">
  <div class="modal-dialog modal-dialog-mod modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="staticBackdropLabel2">PROVA PDF</h5>
        <button type="button" class="btn-close nosha" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div *ngIf="pdfObjectUrl">
          <ngx-extended-pdf-viewer 
            [src]="pdfObjectUrl" 
            [showPrintButton]="false" 
            [showBookmarkButton]="false" 
            [showOpenFileButton]="false" 
            [showSidebarButton]="true"
          >
          </ngx-extended-pdf-viewer>
        </div>
      </div>
      <div class="modal-footer"> FOOTER </div>
    </div>
  </div>
</div>

3. 控制模态框的打开时机(关键优化)

原来的逻辑是点击按钮立刻打开模态框,但此时PDF数据可能还在请求中,容易出现渲染空内容的情况。可以改成等数据加载完成后再打开模态框:

// 替换原来的getDocPreview,改成打开模态框的方法
openPdfModal() {
  this.myService.getDocPreview().subscribe({
    next: (data) => {
      // 重复上面的Blob转换逻辑
      if (data instanceof ArrayBuffer) {
        this.pdfToPreview = new Blob([data], { type: 'application/pdf' });
      } else if (data instanceof Blob) {
        this.pdfToPreview = data.type === 'application/pdf' 
          ? data 
          : new Blob([data], { type: 'application/pdf' });
      }
      this.pdfObjectUrl = URL.createObjectURL(this.pdfToPreview);

      // 数据准备好后,手动打开模态框
      const modalElement = document.getElementById('provaPdfStaticModal');
      if (modalElement) {
        const modal = new (window as any).bootstrap.Modal(modalElement);
        modal.show();
      }
    },
    error: (err) => {
      console.error('加载PDF失败,请检查服务端:', err);
    }
  });
}

对应的HTML按钮修改为:

<button (click)="openPdfModal()"> viewer </button>

最后排查几个细节

  • 确认你的ngx-extended-pdf-viewer是最新版本,旧版本确实存在Blob绑定的兼容性问题
  • 打开浏览器控制台,查看是否有CORS报错、PDF解析错误等信息
  • 检查服务端的响应头,确保Content-Type设置为application/pdf

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 16:12:30