<img>:在资源URL上下文中使用的不安全值


109

自从升级到最新的Angular 2候选版本以来,我的img标签:

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

引发浏览器错误:

原始异常:错误:资源URL上下文中使用的不安全值

网址的值是:

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

编辑:

我已经尝试过在其他解决方案中提出的建议,即这个问题应该是重复的,但是我遇到了同样的错误。

我已将以下代码添加到控制器:

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);
  }

我仍然收到相同的错误消息。

编辑2:

我也将html更改为:

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

我仍然收到相同的错误消息


我不清楚应该改变什么。我是否可以将src =“ {{something.else}}”更改为[src] =“ something.else”?
Bill Noble

1
没错:[src]='theMediaItem.photoURL1'
君特Zöchbauer

是的,我尝试过,但得到了相同的错误消息。
Bill Noble

您正在使用哪个Angular2版本?
君特Zöchbauer

我想我使用的是2.0.0-beta.15(我使用的是离子性的,并且不完全确定如何检查)对于添加代码的方式,我感到很抱歉,协议上还不清楚。
Bill Noble

Answers:


95

我正在使用rc.4,此方法适用于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);
  }
}

在HTML中:

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

使用函数将确保在清除值后该值不会更改。另请注意,您使用的清理功能取决于上下文。

对于图像,bypassSecurityTrustUrl可以使用,但对于其他用途,则需要参考文档

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


3
什么是“ rc4”(后来Helzgate引用RC3)?我的意思是,如何将其映射到github版本?在github和npm中,我只看到2.4.4或2.4.5之类的版本。我目前在2.4.4上,似乎DomSanitizer发生了变化;所以这是您需要的进口商品:import {DomSanitizer} from '@angular/platform-browser';
红豌豆

哦,我认为angular的github 分支将引用2.4.x例如,但是github 标签将引用候选发布,例如2.0.0-rc3。我可以在rc3中看到,例如,该类仍被命名DomSanitizationService
红豌豆

1
this.sanitizer.bypassSecurityTrustResourceUrl(url)对于视频
prayagupd

使用此方法之前,请仔细阅读文档:绕过安全性TrustUrl() 警告: 使用不受信任的用户数据调用此方法会使您的应用程序面临XSS安全风险!在我看来,这样做是不安全的,除非您真的确定图像源是可信任的。即使它来自服务器,如果它是由用户上传的,也有可能利用这种解决方案。
威尔特

144

// 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);
    }
  }
}

模板

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

而已!

注意:您不需要它,但这是管道的组件用途
  // 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');
  }


24

使用安全管道对其进行修复。

  • 如果您还没有,请创建一个安全的管道。

    ng gc管道安全

  • 在app.module.ts中添加安全管道

    声明:[SafePipe]

  • 在您的ts中声明安全管道

导入Dom消毒剂和安全管道以安全地访问URL

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);
  }
}

-使用src网址添加安全

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

2
大!一件事,不是“ ng g pipe safe”而不是“ ng gc pipe safe”,那显然不起作用吗?
Jacob-Jan Mosselman

15

您可以向视图公开消毒剂,也可以公开将调用转发给bypassSecurityTrustUrl的方法。

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

2

默认情况下,Angular将所有值视为不可信。当通过属性,属性,样式,类绑定或插值将值从模板插入DOM时,Angular会清理并转义不受信任的值。

因此,如果您要直接操作DOM并插入其内容,则需要对其进行清理,否则Angular会遇到错误。

我为此创建了管道SanitizeUrlPipe

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

@Pipe({
    name: "sanitizeUrl"
})
export class SanitizeUrlPipe implements PipeTransform {

    constructor(private _sanitizer: DomSanitizer) { }

    transform(v: string): SafeHtml {
        return this._sanitizer.bypassSecurityTrustResourceUrl(v);
    }
}

这就是你可以使用的方式

<iframe [src]="url | sanitizeUrl" width="100%" height="500px"></iframe>

如果要添加HTML,则SanitizeHtmlPipe可以为您提供帮助

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

@Pipe({
    name: "sanitizeHtml"
})
export class SanitizeHtmlPipe implements PipeTransform {

    constructor(private _sanitizer: DomSanitizer) { }

    transform(v: string): SafeHtml {
        return this._sanitizer.bypassSecurityTrustHtml(v);
    }
}

在此处阅读有关角度安全性的更多信息。


1

我通常如下添加单独的safe pipe可重用组件

# Add Safe Pipe

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

@Pipe({name: 'mySafe'})
export class SafePipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) {
    }

    public transform(url) {
        return this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
}
# then create shared pipe module as following 

import { NgModule } from '@angular/core'; 
import { SafePipe } from './safe.pipe';
@NgModule({
    declarations: [
        SafePipe
    ],
    exports: [
        SafePipe
    ]
})
export class SharedPipesModule {
}
# import shared pipe module in your native module

@NgModule({
    declarations: [],
    imports: [
        SharedPipesModule,
    ],
})
export class SupportModule {
}
<!-------------------
call your url (`trustedUrl` for me) and add `mySafe` as defined in Safe Pipe
---------------->
<div class="container-fluid" *ngIf="trustedUrl">
    <iframe [src]="trustedUrl | mySafe" align="middle" width="100%" height="800" frameborder="0"></iframe>
</div>

0
import {DomSanitizationService} from '@angular/platform-browser';
@Component({
 templateUrl: 'build/pages/veeu/veeu.html'
 })
  export class VeeUPage {
     trustedURL:any;
      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.trustedURL  = sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
        } 
 }



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


User property binding instead of function.

0

可以将图像设置为背景图像以避免unsafe url错误:

<div [style.backgroundImage]="'url(' + imageUrl + ')'" class="show-image"></div>

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.