[Fixed] Angular: PDF in an iframe wont show if too big

Issue

I have a angular webapp which shows and compares pdf files, but when the size of a pdf file is too big (larger than 1,3 MB from my observations) it doesn’t show it. I’m using an iframe to show it. The file source is a base64 String (the source is correct, since I tested it in an online base64 to pdf converter and it shows all these files which my app does not).

Here’s my code (html component):

<div *ngIf="seite && pdfObj; else loadingPDFs">
  <as-split style="height: 1080px;" direction="horizontal" unit="percent">
    <as-split-area size="50">
      <div class="text-center" style="height: 100vh; padding-left: 0.8em;">
        <span class="badge badge-warning tag">Gemeldete Seite</span>
        <iframe width="100%" height="100%" [src]="seite.inhalt"></iframe>
      </div>
    </as-split-area>
    <as-split-area size="50">
      <div class="text-center" style="height: 100vh; padding-right: 0.8em;">
        <span class="badge badge-success tag center">Original Seite</span>
        <iframe width="100%" height="100%" [src]="pdfObj"></iframe>
      </div>
    </as-split-area>
  </as-split>
</div>
<ng-template #loadingPDFs>
  <mat-spinner></mat-spinner>
</ng-template>

And the code of my ts-component:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { take } from 'rxjs/operators';
import { DomSanitizer } from '@angular/platform-browser';
// Service Imports
import { SeiteService } from 'app/services/seite.service';
import { BuchService } from 'app/services/buch.service';
// Class Imports
import { Seite } from '../classes/seite';


@Component({
  selector: 'app-seiten-compare',
  templateUrl: './seiten-compare.component.html',
  styleUrls: ['./seiten-compare.component.scss']
})
export class SeitenCompareComponent implements OnInit {

  seite: Seite;
  pdfObj: any;

  constructor(
    private route: ActivatedRoute,
    private location: Location,
    private buchService: BuchService,
    private seiteService: SeiteService,
    private sanitizer: DomSanitizer
  ) { }

  ngOnInit(): void {
    this.getSeite();
  }

  getSeite() {
    this.seiteService.getSeiteByID(parseInt(this.route.snapshot.paramMap.get('id'), 10))
    .pipe(take(1))
    .subscribe(seite => {
      seite.inhalt = this.sanitizer.bypassSecurityTrustResourceUrl('data:application/pdf;base64,' + seite.inhalt);
        this.getPDFSource(seite.outputRoot);
        this.seite = seite;
      });
  }

  getPDFSource(fileAbsolutePath: string): void {
    this.buchService.getPDF(fileAbsolutePath)
    .pipe(take(1))
    .subscribe(source => {
      this.pdfObj = this.sanitizer.bypassSecurityTrustResourceUrl('data:application/pdf;base64,' + source.pdf);
    });
  }
}

As I said, the functions in my services and API return the correct pdf source, as tested online (https://base64.guru/converter/decode/pdf).
I checked 60 PDF files and in the app ALL PDFs with a file size of max 1,33MB were shown and all above that did not show in my app.

Does anyone have a solution or idea as to why it’s not working?
Any help is much appreciated!

Solution

Some browsers have a hard limit on URL length, it’s possible you are exceeding it.

You pass the PDF as a data URL in this line <iframe width="100%" height="100%" [src]="pdfObj"></iframe>. Setting an iframe src has the same URL length limitations as redirecting to the URL.

This other question discusses URL length limitations per browser: Data protocol URL size limitations

Leave a Reply

(*) Required, Your email will not be published