4
votes

I trying to do image preview with angular using fileReader and creating data url, but the image never loads the svg, but jpg and etc. works.

example: stackblitz

I also tryed to take it as plain text and add it as innerHtml to div which works ,but the image have width: 100mm and height: 100mm, which means the image doens't scale to its container. I tryed to change this in css but it didn't work either...

example: stackblitz

I also added some svg img to src DIR for testing.

1

1 Answers

7
votes

This happens because of security. The difference between svg and jpg/png is in the structure since svg uses xml and the jpg/png are bitmaps. So when they are translated to base64 svg is untrusted and jpg/png is trusted.

As Angular documentation says

For example, when binding a URL in an hyperlink, someValue will be sanitized so that an attacker cannot inject e.g. a javascript: URL that would execute code on the website.

More simple way

You can just add bypassSecurityTrustUrl() to your method

So it will look like this

  selectedImageChanged(event) {
    const fileReader = new FileReader();
    fileReader.onload = async e => {
      const value = this.sanitizer.bypassSecurityTrustUrl(fileReader.result as string);
      this.previewFileUrl = value;
    }
    fileReader.readAsDataURL(event.target.files[0]);
  }

More complex way

The second possible way is to create a pipe which will do the same.

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';

@Pipe({
  name: 'safe'
})
export class SafePipe implements PipeTransform {

  constructor(protected sanitizer: DomSanitizer) {}

 public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
    switch (type) {
            case 'html': return this.sanitizer.bypassSecurityTrustHtml(value);
            case 'style': return this.sanitizer.bypassSecurityTrustStyle(value);
            case 'script': return this.sanitizer.bypassSecurityTrustScript(value);
            case 'url': return this.sanitizer.bypassSecurityTrustUrl(value);
            case 'resourceUrl': return this.sanitizer.bypassSecurityTrustResourceUrl(value);
            default: throw new Error(`Invalid safe type specified: ${type}`);
        }
  }
}

The use of this pipe is very simple in your code it would look like this.

<img [src]="previewFileUrl | safe: 'url'" alt=alt/>

Stackblitz demo

Don't forget to put the SafePipe into module dependencies.