Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

<img>: Unsafe value used in a resource URL context

Tags:

angular

Since upgrading to the latest Angular 2 release candidate, my img tags:

<img class='photo-img' [hidden]="!showPhoto1" src='{{theMediaItem.photoURL1}}'>

are throwing a browser error:

ORIGINAL EXCEPTION: Error: unsafe value used in a resource URL context

The value of the url is:

http://veeu-images.s3.amazonaws.com/media/userphotos/116_1464645173408_cdv_photo_007.jpg

EDIT:

I have tried the suggestion made in the other solution that this question is supposed to be a duplicate of but I am getting the same error.

I have added the following code to the controller:

import {DomSanitizationService} from '@angular/platform-browser';

@Component({
  templateUrl: 'build/pages/veeu/veeu.html'
})
export class VeeUPage {
  static get parameters() {
    return [[NavController], [App], [MenuController], [DomSanitizationService]];
  }

  constructor(nav, app, menu, sanitizer) {

    this.app = app;
    this.nav = nav;
    this.menu = menu;
    this.sanitizer = sanitizer;

    this.theMediaItem.photoURL1 = this.sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
  }

I am still getting the same error message.

EDIT2:

I have also changed the html to:

<img class='photo-img' [hidden]="!showPhoto1" [src]='theMediaItem.photoURL1'>

I still get the same error message

like image 593
Bill Noble Avatar asked Jun 20 '16 16:06

Bill Noble


4 Answers

Pipe

    // Angular
    import { Pipe, PipeTransform } from '@angular/core';
    import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from '@angular/platform-browser';
    
    /**
     * Sanitize HTML
     */
    @Pipe({
      name: 'safe'
    })
    export class SafePipe implements PipeTransform {
      /**
       * Pipe Constructor
       *
       * @param _sanitizer: DomSanitezer
       */
      // tslint:disable-next-line
      constructor(protected _sanitizer: DomSanitizer) {
      }
    
      /**
       * Transform
       *
       * @param value: string
       * @param type: string
       */
      transform(value: string, 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:
            return this._sanitizer.bypassSecurityTrustHtml(value);
        }
      }
    }

Template

{{ data.url | safe:'url' }}

That's it!

Note: You shouldn't need it but here is the component use of the pipe

      // Public properties
      itsSafe: SafeHtml;

      // Private properties
      private safePipe: SafePipe = new SafePipe(this.domSanitizer);
    
      /**
       * Component constructor
       *
       * @param safePipe: SafeHtml
       * @param domSanitizer: DomSanitizer
       */
      constructor(private safePipe: SafePipe, private domSanitizer: DomSanitizer) {
      }
    
      /**
       * On init
       */
      ngOnInit(): void {
        this.itsSafe = this.safePipe.transform('<h1>Hi</h1>', 'html');
      }
like image 124
Post Impatica Avatar answered Nov 16 '22 05:11

Post Impatica


I'm using rc.4 and this method works for ES2015(ES6):

import {DomSanitizationService} from '@angular/platform-browser';

@Component({
  templateUrl: 'build/pages/veeu/veeu.html'
})
export class VeeUPage {
  static get parameters() {
    return [NavController, App, MenuController, DomSanitizationService];
  }

  constructor(nav, app, menu, sanitizer) {

    this.app = app;
    this.nav = nav;
    this.menu = menu;
    this.sanitizer = sanitizer;    
  }

  photoURL() {
    return this.sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
  }
}

In the HTML:

<iframe [src]='photoURL()' width="640" height="360" frameborder="0"
    webkitallowfullscreen mozallowfullscreen allowfullscreen>
</iframe>

Using a function will ensure that the value doesn't change after you sanitize it. Also be aware that the sanitization function you use depends on the context.

For images, bypassSecurityTrustUrl will work but for other uses you need to refer to the documentation:

https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizer-class.html

like image 41
elkelk Avatar answered Nov 16 '22 04:11

elkelk


The most elegant way to fix this: use pipe. Here is example (my blog). So you can then simply use url | safe pipe to bypass the security.

<iframe [src]="url | safe"></iframe>

Refer to the documentation on npm for details: https://www.npmjs.com/package/safe-pipe

like image 58
Filip Molcik Avatar answered Nov 16 '22 05:11

Filip Molcik


Use Safe Pipe to fix it.

  • Create a safe pipe if u haven't any.

    ng g pipe safe

  • add Safe pipe in app.module.ts

    declarations: [SafePipe]

  • declare safe pipe in your ts

Import Dom Sanitizer and Safe Pipe to access url safely

import { Pipe, PipeTransform} from '@angular/core';
import { DomSanitizer } from "@angular/platform-browser";

@Pipe({ name: 'safe' })

export class SafePipe implements PipeTransform {

constructor(private sanitizer: DomSanitizer) { }
transform(url) {
 return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}
  • Add safe with src url

    <img width="900" height="500" [src]="link | safe"/>

like image 44
sjsj15 Avatar answered Nov 16 '22 04:11

sjsj15