CodeZine(コードジン)

特集ページ一覧

AngularJSのDOMイベント処理と注意すべきディレクティブを知り、HTMLテンプレートを使いこなそう

AngularJSで初めるJavaScriptフレームワーク開発スタイル 第8回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2015/05/07 14:00
目次

コンテンツセキュリティポリシーへ対応する - ngCsp

 最近のAjaxなどを使ってのHTMLの場合にはXSS(クロスサイトスクリプティング)などの脆弱性が入り込みやすいという問題があります。

 このような問題に対応するために、ブラウザもセキュリティを高いモードで動作できるようにしたものが、「コンテンツセキュリティポリシー(以下CSP)」です。

 簡単に言えば、JavaScript内でのeval()の実行を禁止したり、また、HTML内でscriptタグ内にJavaScriptを記述できる機能を無効にしたりと、これ以外にも細かくルールを規定することができます。

 CSPを有効にするにはリスト8に示すようにHTTPヘッダに"Content-Security-Policy"というヘッダを追加します。

 ただし、すべてのブラウザでサポートしているわけではなく比較的新しいブラウザのみとなっていて、Can I Useなどを参照すればどのブラウザで利用できるかを調べることができます。

リスト9 CSPを有効にする為のヘッダ
Content-Security-Policy: default-src 'self'
X-Content-Security-Policy: default-src 'self'

 ここではCSPの詳細な設定方法を説明しませんが、詳しくはMDNなどを参照すると理解できます。

 もともとAngularJSはCSPを意識した作りになっていますが、CSPを有効にしたときに以下の2つの処理に影響が発生します。

  • $scope内の変数をHTMLテンプレートから取得する場合などで実行速度を優先するため「new Function(string)」を行う部分
  • インラインCSSをHTML内に追加する部分(ng-cloak等)

 new Function(string)を使わないようにする為には、ng-cspディレクティブをHTML要素に記述します。そして、インラインCSSの対応は代わりにangular-csp.cssを読みこむようにします。

 リスト10はこれらの対応を行った後のサンプルコードです。

リスト10 ngCspの利用例(ngnonbindable.htmlの抜粋)
<html ng-csp>
    <head>
        : // 省略
        <link rel="stylesheet" href="../css/angular-csp.css">
    </head>
    <body ng-app="app">
      : // 省略
    </body>
</html>

 ng-cspを設定しても図5のようなエラーが発生する場合には、指定する場所が間違っているので、HTML要素に正しく記述してあるか確認してください。

図5 ngCspの指定が間違っている場合に表示されるエラー
図5 ngCspの指定が間違っている場合に表示されるエラー

 なお、ng-cspディレクティブを明示しても、eval等の実行ができるようになるわけではないので、自分で記述するコードはCSPの制限にそった実装をする必要があります。

 CSPは、開発者が指定するというよりは、サイトの管理者によって指定される場合が多いと思います。現在は必要なくても、必要になったときにそのまま動作することが望ましくあります。

 このようにAngularJSはこのようなセキュリティに関しても十分考慮されたフレームワークだと言えます。

モデルの変更タイミングを指定する - ngModelOptions

 このディレクティブは1.3で新たに導入されたディレクティブですので、1.2以前のバージョンを指定している場合には利用できませんが、入力フォームなどで指定したモデルの変更タイミングを指定することができる便利なディレクティブです。

 例えば、郵便番号を入力すると自動的に住所が反映される用途の場合、入力カーソルがはずれた時にAjaxなどでサーバ機能と連携がしたくなります。その場合にngModelOptionsは大変有効な機能です。

 リスト11は、blurイベントをモデルの変更タイミングに指定し、イベントの発生を500ミリ秒後に発生するように指定します。

 これで、500ミリ秒以内に複数回blurイベントが発生しても最後のblurイベントのみが有効になります。

リスト11 ngModelOptionsを用いた変更タイミングの指定方法(ngmodel_options.htmlの抜粋)
<div ng-init="name = '';"></div>
<input type="text" ng-model="name" ng-model-options="{ updateOn : 'blur', debounce : 500 }" >
<br />
あなたが入力した値は「<b>{{name}}</b>」です

 変更が発生したタイミングで処理をするには、リスト11のように$scope.$watchメソッドを使えば目的となる処理が行えます。

リスト12 $scope.$watchを用いた値の変更タイミングの把握 (ngmodel_options.htmlの抜粋)
app.controller('changeController',['$scope',function($scope){
    $scope.name = '';
    $scope.$watch('name',function(newValue,oldValue){
        if(newValue){
            console.log(newValue);
            // 何か処理をする
        }
    })
}]);

 表2は指定できるオプションの一覧です。ここで指定したオプション以外もありますので、詳しく知りたい場合には、リファレンスを参照してください。

表2 利用できるオプション一覧
指定できるオプション 説明
updateOn 変更を行うタイミングのイベント
debounce 変更イベントを指定した時間(ミリ秒)だけ遅らせる
allowInvalid 無効なデータでのモデル値を許容するか
getterSetter getter/setterを利用したアクセスを行うようにする
timezone inputでtime='date'もしくは'time'を指定した時のタイムゾーンの指定

最後に

 これまで紹介してきたように、AngularJSのビルトインディレクティブだけでも十分な機能を持っています。

 しかし、AngularJSではこのディレクティブ機能を利用して、比較的簡単に独自タグや独自属性を作ることができます。その機能を利用したサードパーティ製のディレクティブなども多々あります。

 例えば、今回説明したDOMイベントでビルトインで用意されていないイベントを扱う際には、Event Binderを利用して拡張が可能です。

 近日中に、いよいよAngularJS 1.4がリリースとなりそうです。少々大きな変更になり影響が出てくる開発者の方も出てくると思いますので、次回は少々予定を変更してAngularJSの1.4での新機能や注意すべき機能などを紹介したいと思います。

参考資料



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

バックナンバー

連載:AngularJSではじめるJavaScriptフレームワーク開発スタイル

もっと読む

著者プロフィール

  • WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。個人紹介主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしど...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5