Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular svg image preview

Tags:

angular

svg

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.

like image 394
Pavel B. Avatar asked Mar 04 '23 02:03

Pavel B.


1 Answers

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 <a [href]="someValue"> hyperlink, someValue will be sanitized so that an attacker cannot inject e.g. a javascript: URL that would execute code on the website.

WARNING: calling this method with untrusted user data exposes your application to XSS security risks!

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: 'unSafe'
})
export class UnSafePipe 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 | unSafe: 'url'" alt=alt/>

Stackblitz demo

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

like image 105
Josef Katič Avatar answered Mar 16 '23 18:03

Josef Katič