19

I am trying to sanitize a pdf url and want to assign it to a string type variable so that I can use it for pdf viewer. Is there any way to do that? If I use any type for pdfSrc type, I am getting Invalid parameter object: need either .data, .range or .url in the <pdf-viewer>.

Note: The URL which I used is for reference purpose, i would use external URLs in that place

landingpage.component.ts

import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';

export class LandingpageComponent implements OnInit {
     public pdfSrc: string;
}

constructor(    
    private sanitizer: DomSanitizer) {
}

fnOpenAsset() {     
   let url = 'http://localhost/pdf_viewer-master/18/docs/pdf.pdf';
   this.pdfSrc = this.sanitizer.bypassSecurityTrustResourceUrl(url);
}

landingpage.component.html

<pdf-viewer class="alignComponentCenter" [src]="pdfSrc" 
</pdf-viewer>
Muthu
  • 808
  • 1
  • 9
  • 23

5 Answers5

44

I got a way to fix this. I tried sanitizing the SafeResourceUrl again with sanitize() method whose return value is string | null.

In case you want to use bypassSecurityTrustUrl(), then SecurityContext.URL will take place. In my case I used SecurityContext.RESOURCE_URL


export class LandingpageComponent implements OnInit {
     public pdfSrc: string;
}

constructor(    
    private sanitizer: DomSanitizer) {
}

fnOpenAsset() {     
   let url = 'http://localhost/pdf_viewer-master/18/docs/pdf.pdf';
   this.pdfSrc = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, this.sanitizer.bypassSecurityTrustResourceUrl(url));
}
Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116
Muthu
  • 808
  • 1
  • 9
  • 23
1

As already suggested, you can just remove the variable declaration (or declare any type), but I doubt many would agree to be the correct solution.

The various Dom sanitizer methods don't return strings, they return various object types.

See the official API docs: https://angular.io/api/platform-browser/DomSanitizer

this.sanitizer.bypassSecurityTrustResourceUrl(url);

Returns a SafeResourceUrl type object, not a string; so your declaration should reflect this rather than the nebulous any type.

Krenom
  • 1,894
  • 1
  • 13
  • 20
  • if I use ```any``` type, I am getting ```Invalid parameter object: need either .data, .range or .url``` in the `````` That's y i want to make that as string. Is there any way? – Muthu Apr 25 '19 at 12:53
1

Future solution

There are efforts from the angular team to make the usage of Safe* types more flexible. As far as I understand issue #33028 on the angular github page they are currently enabling the direct use of Safe* types as string. That way you could be using bypassSecurityTrustResourceUrl() and directly assign the return value to the src property. Excactly as @Muthu tried it initially.

this.pdfSrc = this.sanitizer.bypassSecurityTrustResourceUrl(url);

This would affect the following types (as they all extend the SafeValue interface):

  • SafeHtml
  • SafeUrl
  • SafeResourceUrl
  • SafeScript
  • SafeStyle

Current solution

For now it seems like the best workaround to access the actual string is to re-sanitize the Safe* value, just like @Muthu points it out in his accepted answer.

Alternatively one can either use any type or force the return value to be a string by using as string after calling the function. Note that this only works for certain scenarios, e.g. assigning HTML code from SafeHtml.

let html: any = this.sanitizer.bypassSecurityTrustHtml("<h1>just some html!</h1>");
let html2: string = this.sanitizer.bypassSecurityTrustHtml("<h1>even more html!</h1>") as string;
JR46
  • 11
  • 2
0

This actually solved my problem of unable to assign SafeResourceUrl to a string

Here is the solution of my. However, I am not sure if this will cause some security problem, I am using this code for my small project, I am open for any criticism and improvement.

dir: SafeResourceUrl;

downloadLink.href = this.dir['changingThisBreaksApplicationSecurity'];

Why 'changingThisBreaksApplicationSecurity'?

When you console.log the dir which has the type of SafeResourceUrl, you will see this changingThisBreaksApplicationSecurity property exist in it, and it consist of the blob link you need.

-2

Just keep public pdfSrc without any type. It will automatically cast the required type.

import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';

public pdfSrc;

constructor(private sanitizer: DomSanitizer) {
}

fnOpenAsset() {     
   let url = 'http://localhost/pdf_viewer-master/18/docs/pdf.pdf';
   this.pdfSrc = this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81