2014-01-08 10 views
12

OAuthで保護されたバックエンドから画像を読み込むAngularJSアプリケーションを作成しました。私のOAuthライブラリは、Angular $httpProviderに余分なインターセプタを追加して、正しい認証ヘッダーを追加することによって構成されています。動的ngSrcリクエストでHTTPインターセプタを強制する

HTMLテンプレートでの私のソースコードは次のようになります。

<img ng-src="{{ '/users/1/images/' + imageId }}"> 

私の問題はngSrcディレクティブによって作成されたHTTPリクエストはリクエストとその結果$http実装によって無視されていることです間違った認証。 正常なAPI関数が正しく呼び出されます($http$resourceを直接使用して、コントローラ/サービスによって呼び出されたもの)。

答えて

10

ngSrcディレクティブは、imgの通常のsrc属性を制御するだけで、ブラウザがJavascript経由ではなく他のイメージと同じようにイメージを要求するため、これを傍受することはできません。

しかし、あなたができることは、httpSrcを保存して、新しい指令を書くことです。これにより、$httpの呼び出しを使用してイメージを取得し、Using raw image data from ajax request for data URIなどのレスポンスを使用してデータURIを作成できます(ブラウザのサポートは不明ですが)。

+0

感謝を。私はすでにこれを検討していましたが、Base64の複数のチャンクを追加すると、DOMへのパフォーマンスの影響が心配です。きれいで上品な解決策があることを願っていました。 –

0

これはもう少し古いですが、インターセプターを使用してイメージを見つける別の方法を追加すると考えました。私の場合、私はレールの資産パイプラインから画像パスを見つける必要がありました。

Codetunes(http://codetunes.com/2014/5-tips-on-how-to-use-angularjs-with-rails-that-changed-how-we-work/)のブログでテンプレートの検索方法が説明されています。これはインターセプターを使用しますが、イメージでは機能しません。

私が使用した解決方法では、ng-src値のモデルを使用する必要があります。モデル内では、上記のブログ記事のRails.templates変数設定を利用するサービスからヘルパーメソッドを呼び出します。

だから、それは次のようになります。

angular.module('myApp').factory('RailsAssetService', function(Rails) { 

    function RailsAssetService() { 

    } 

    RailsAssetService.getAssetsUrl = function(url) { 
     var railsUrl = Rails.templates[url]; 
     if (railsUrl === undefined) 
      railsUrl = url; 
     return railsUrl; 
    } 

    return RailsAssetService; 
}); 

とコントローラで:

vm.creditCardsImage = RailsAssetService.getAssetsUrl('credit-cards-logo.gif'); 

とビューで:

<img ng-src="{{vm.creditCardsImage}}"> 
20

ミハエルの答えディレクティブができたに基づいて、以下のように見える

次のように0
app.directive('httpSrc', [ 
     '$http', function ($http) { 
      var directive = { 
       link: link, 
       restrict: 'A' 
      }; 
      return directive; 

      function link(scope, element, attrs) { 
       var requestConfig = { 
        method: 'Get', 
        url: attrs.httpSrc, 
        responseType: 'arraybuffer', 
        cache: 'true' 
       }; 

       $http(requestConfig) 
        .then(function(response) { 
         var arr = new Uint8Array(response.data); 

         var raw = ''; 
         var i, j, subArray, chunk = 5000; 
         for (i = 0, j = arr.length; i < j; i += chunk) { 
          subArray = arr.subarray(i, i + chunk); 
          raw += String.fromCharCode.apply(null, subArray); 
         } 

         var b64 = btoa(raw); 

         attrs.$set('src', "data:image/jpeg;base64," + b64); 
        }); 
      } 

     } 
    ]); 

あなたはそれを使用することになり

<img http-src="www.test.com/something.jpeg"> 
+0

それは完璧に動作します! – wmfairuz

+0

こんにちは、私はこの指示を使用しています - 定義されているように定義されたhttp-srcが各繰り返しで再計算されていないように見えるので、変更し続けるイメージを指し示すと更新されません。何かご意見は? – user1361529

+1

cache: 'false'? – Marcus

4

としては、(あなたがBowerを使用している場合bower install --save angular-img-http-src)あなたはangular-img-http-srcを使用することができhere言いました。

あなたはthe codeを見れば、それはそうlook if your browser supports it 4月2016 19日にstill draftありURL.createObjectURLURL.revokeObjectURLを使用しています。それを使用するためには

、アプリのモジュール(angular.module('myapp', [..., 'angular.img']))への依存関係として'angular.img'を宣言した後、あなたのHTMLにあなたは<img>タグのhttp-src属性を使用することができます。あなたの例では

、あなたが書くことができます:<img http-src="https://stackoverflow.com/users/1/images/{{imageId}}">

+0

ブラウザのサポートが受け入れ可能であると仮定して、オブジェクトURLを使用することはデータURIを使用するという私の元の答えより優れています。 –

関連する問題