ChromeApps外部リソース(画像)取得用のAngularJS Directive
はじめに
はじめて作ったChromeAppで外部から取得した画像が表示されない問題がありましたが、なんとか解決したのでメモします。
画像が表示されていなかった
コンソールに表示されているエラーは以下です。
Refused to load the image 'https://api.indiesquare.me/wallet/get_asset_image?asset=ZONO' because it violates the following Content Security Policy directive: "img-src 'self' blob: filesystem: data: chrome-extension-resource:".
解決策1 XMLHttpRequestを使ってresponseTypeにblobを設定する
公式サイトに解決策がいくつか書いてあります。1つ目はXMLHttpRequestを利用してresponseTypeをblobにする方法です。
var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://api.is-dev1.agileworks.jp/v2/token/image?name=ZONO', true); xhr.responseType = 'blob'; xhr.onload = function(e) { var img = document.createElement('img'); img.setAttribute('width', '100px'); img.setAttribute('height', '100px'); img.src = window.URL.createObjectURL(this.response); document.body.appendChild(img); }; xhr.send();
無事画像が表示されています。でもちょっとコード量が多い気がします。
解決策2 webviewを使う
<webview src="https://api.is-dev1.agileworks.jp/v2/token/image?name=ZONO" width="100" height="100"></webview>
"permissions": ["webview"],
画像は出ていますが画像サイズの調整ができてないようです。
解決策3
webviewの方が実装は簡単ですが、解決策1のXMLHttpRequestが正しい解決方法な気がします。解決策1はコード量が多いのでAngularJSのDirectiveを作りました。
coin.directive('blobimg', function() { return { restrict: 'E', replace: true, scope: { name: '@', css: '@' }, template: '<span></span>', link: function($scope, iElement) { var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://api.is-dev1.agileworks.jp/v2/token/image?name=' + $scope.name, true); xhr.responseType = 'blob'; xhr.onload = function(e) { var img = document.createElement('img'); img.classList.add($scope.css); img.src = window.URL.createObjectURL(this.response); iElement[0].appendChild(img); }; xhr.send(); } }; });
<blobimg name={{b.asset}} css="token-image-small"></blobimg>{{b.asset}}
結果
まとめ
画像が正しく表示されています。directiveを使うことでアプリ内で共通して利用できそうです。ソースはgithubに置いています。
参考
Laravelで画像処理(アップロード/リサイズ/サムネイル)を行なう方法
ng-mtg#6 AngularJS ディレクティブ・パターン