Angular TIPS

Angular TIPS

インラインフレームに外部リソースをバインドするには?(Property Binding)

2017年10月23日

セキュリティの観点からデフォルトではiframeのsrc属性やobjectのdata属性にはプロパティバインディングできない。これを回避して信頼できる値としてバインディングする方法を説明する。

  • このエントリーをはてなブックマークに追加

【対応バージョン】 Angular 4以降。v4時点で執筆しました。

 別稿「TIPS:ビューにHTML文書をバインドするには?」でも触れたように、Angularでは外からのリソースの取り込みに対して一定の制限を課しています。

 例えば、<iframe>要素のsrc属性、<object>要素のdata属性などへのProperty Bindingはデフォルトでは許可されていません。まずは、以下のサンプルで確認してみましょう。

TypeScript
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <!--src属性にsiteプロパティの値をバインド-->
  <iframe [src]="site"></iframe>
  `,
})
export class AppComponent  { 
  site = 'http://www.wings.msn.to/';
}
インラインフレームにバインドするためのコード(app.component.ts)

 果たして、このコードは「unsafe value used in a resource URL context」のようなエラーで動作しません(エラーメッセージは開発者ツールで確認できます)。バインド構文で動的にインポートされた外部リソースは、時として、セキュリティリスクとなる可能性があるので、まずはバインド構文でのリソース指定を禁止しているわけです。

 このようなコードを動作させるには、DomSanitizerクラスのbypassSecurityTrustResourceUrlメソッドで、リソースが信頼できることを宣言します。以下は、上のコードを修正したものです。

TypeScript
import { Component } from '@angular/core';
import { DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  template: `
  <iframe [src]="safeSite"></iframe>
  `,
})
export class AppComponent  { 
  safeSite: SafeResourceUrl;
  site = 'http://www.wings.msn.to/';

  constructor(private sanitizer: DomSanitizer) {
    this.safeSite = sanitizer.bypassSecurityTrustResourceUrl(this.site);
  }
}
引用するリソースが信頼できることを宣言するコード(app.component.ts)
指定されたサイトをインラインフレームで表示
指定されたサイトをインラインフレームで表示

 今度は、指定されたサイトがインラインフレームで表示されていることを確認してください。bypassSecurityTrustResourceUrlメソッドの戻り値は、SafeResourceUrlオブジェクトです。これでProperty Bindingは、与えられたリソースをそのまま取り込むようになります。

 ただし、ここで誤解してはいけないのが、bypassSecurityTrustResourceUrlメソッドがリソースの内容を検証しているわけでも保証しているわけでもない、という点です。bypassSecurityTrustResourceUrlメソッドは、あくまで「指定されたリソースが信用できる(Trust)ことをマークしている」にすぎません。

 リソースの信頼性を確認するのはあくまでアプリ開発者の仕事なので、無条件にbypassSecurityTrustResourceUrlメソッドを呼び出してはいけません。

処理対象:テンプレート構文(Template Syntax) カテゴリ:基本
処理対象:Property Binding(プロパティバインディング) カテゴリ:テンプレート構文(Template Syntax)
処理対象:バインディング構文(Binding Syntax) カテゴリ:テンプレート構文(Template Syntax)
処理対象:セキュリティ カテゴリ:基本
処理対象:安全な値の信頼(Trusting safe values) カテゴリ:セキュリティ
API:DomSanitizer カテゴリ:@angular > platform-browser > CLASS(クラス)
API:SafeResourceUrl カテゴリ:@angular > platform-browser > INTERFACE(インターフェース)

※以下では、本稿の前後を合わせて5回分(第24回~第28回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

24. 要素のスタイルプロパティを操作するには?(Style Binding)

「[style.スタイルプロパティ名] = "式"」というバインディング構文により、要素に対する任意のCSSスタイルプロパティに値をバインドできるStyle Bindingの、基本的な使い方を説明する。

25. スタイルプロパティに単位付きの値を設定するには?(Style Binding)

Style Bindingの「[style.スタイルプロパティ名.単位] = "式"」というバインディング構文によって、要素に対する任意のCSSスタイルプロパティに単位付きで値をバインドする方法を説明する。

26. 【現在、表示中】≫ インラインフレームに外部リソースをバインドするには?(Property Binding)

セキュリティの観点からデフォルトではiframeのsrc属性やobjectのdata属性にはプロパティバインディングできない。これを回避して信頼できる値としてバインディングする方法を説明する。

27. 要素に適用するスタイルクラスを操作するには?(Class Binding)

スタイルシートとして定義した対象クラスのスタイルを、任意の要素のclass属性に簡単に着脱できるClass Bindingの基本的な使い方を説明する。

28. 配列の内容を順に出力するには?(ngFor)

配列の内容を順に出力できるngForディレクティブ(=ngForOfディレクティブ)の基本的な使い方を説明。また、ngForディレクティブで利用できる特殊変数についてまとめる。

サイトからのお知らせ

Twitterでつぶやこう!