<img>:リソースURLコンテキストで使用される安全でない値


109

最新のAngular 2リリース候補にアップグレードしてから、私のimgタグ:

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

ブラウザエラーを投げています:

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

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

引き続き同じエラーメッセージが表示されます。

EDIT2:

また、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

回答:


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 2017

これを使用する前にドキュメントを注意深くお読みください:bypassSecurityTrustUrl() 警告: 信頼できないユーザーデータでこのメソッドを呼び出すと、アプリケーションが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

Safe Pipeを使用して修正してください。

  • ない場合は安全なパイプを作成します。

    ng gc pipe safe

  • app.module.tsにセーフパイプを追加する

    宣言:[SafePipe]

  • TSで安全なパイプを宣言する

Dom SanitizerとSafe Pipeをインポートして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 urlで金庫を追加

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

2
すごい!1つは、「ng gc pipe safe」の代わりに「ng g pipe safe」ではないのですが、明らかに何が機能しないのですか?
Jacob-Jan Mosselman

15

サニタイザーをビューに公開するか、または呼び出しをbypassSecurityTrustUrlに転送するメソッドを公開できます。

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

2

Angularはデフォルトですべての値を信頼できないものとして扱います。プロパティ、属性、スタイル、クラスバインディング、または補間を介してテンプレートからDOMに値が挿入されると、Angularは信頼できない値を無害化してエスケープします。

そのため、DOMを直接操作してコンテンツを挿入する場合は、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;        
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.