web-dev-qa-db-ja.com

AngularJsによって外部リソースがロードされていません

AngularとPhonegapを使用して、リモートサーバーにあるビデオをロードしようとしましたが、問題が発生しました。私のJSONでは、URLはプレーンなHTTP URLとして入力されています。

"src" : "http://www.somesite.com/myvideo.mp4"

私のビデオテンプレート

 <video controls poster="img/poster.png">
       <source ng-src="{{object.src}}" type="video/mp4"/>
 </video>

私の他のすべてのデータはロードされますが、私のコンソールを見ると、私はこのエラーが出ます:

Error: [$interpolate:interr] Can't interpolate: {{object.src}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy.  URL

私は私の設定で$compileProviderを追加しようとしましたが、それは私の問題を解決しませんでした。

$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);

このクロスドメイン問題についての投稿 sを見ましたが、どうやってこれを解決するのか、どの方向に進むべきかわかりません。で。任意のアイデア?任意の助けは大歓迎です

191
mhartington

これは私のために働いた唯一の解決策です:

var app = angular.module('plunker', ['ngSanitize']);

app.controller('MainCtrl', function($scope, $sce) {
  $scope.trustSrc = function(src) {
    return $sce.trustAsResourceUrl(src);
  }

  $scope.movie = {src:"http://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});

そしてiframeの中で:

<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrc(movie.src)}}" allowfullscreen frameborder="0">

http://plnkr.co/edit/tYq22VjwB10WmytQO9Pb?p=preview

265
Guy Sopher

もう1つの簡単な解決策は、フィルタを作成することです。

app.filter('trusted', ['$sce', function ($sce) {
    return function(url) {
        return $sce.trustAsResourceUrl(url);
    };
}]);

それからng-srcでフィルタを指定します。

<video controls poster="img/poster.png">
       <source ng-src="{{object.src | trusted}}" type="video/mp4"/>
</video>
266
David Boyd

$ sceDelegateProviderでリソースをホワイトリストに登録します

これは、Angular 1.2に設定された新しいセキュリティポリシーが原因です。ハッカーによるダイヤルアウト(つまり、ペイロードを含む可能性がある外部URLへの要求の作成)を防ぐことで、XSSをより困難にします。

これを適切に回避するには、次のように、許可したいドメインをホワイトリストに登録する必要があります。

angular.module('myApp',['ngSanitize']).config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist([
    // Allow same Origin resource loads.
    'self',
    // Allow loading from our assets domain.  Notice the difference between * and **.
    'http://srv*.assets.example.com/**'
  ]);

  // The blacklist overrides the whitelist so the open redirect here is blocked.
  $sceDelegateProvider.resourceUrlBlacklist([
    'http://myapp.example.com/clickThru**'
  ]);
});

この例はあなたがここで読むことができるドキュメンテーションから持ち上げられます:

https://docs.angularjs.org/api/ng/provider/$sceDelegateProvider

これを機能させるには、必ずアプリケーションにngSanitizeを含めてください。

機能を無効にする

この便利な機能を無効にしたいが、あなたのデータが安全であると確信しているなら、あなたは単純に**を許可することができます。

angular.module('app').config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist(['**']);
});
74
superluminary

ここでも同じ問題がありました。 YouTubeのリンクにバインドする必要がありました。 グローバルな解決策として私にとってうまくいったのは、私の設定に以下を追加することでした:

.config(['$routeProvider', '$sceDelegateProvider',
        function ($routeProvider, $sceDelegateProvider) {

    $sceDelegateProvider.resourceUrlWhitelist(['self', new RegExp('^(http[s]?):\/\/(w{3}.)?youtube\.com/.+$')]);

}]);

そこに 'self'を追加することが重要です。そうしないと、どのURLにもバインドできません。から 角度のドキュメント

'self' - 特殊な文字列 'self'を使用して、同じプロトコルを使用しているアプリケーション文書と同じドメインのすべてのURLと突き合わせることができます。

これで、YouTubeのリンクに直接バインドできるようになりました。

明らかにあなたのニーズに合わせて正規表現をカスタマイズする必要があります。それが役に立てば幸い!

20
zumek

この問題を解決するための最善かつ簡単な解決策は、コントローラのこの機能からデータを渡すことです。

$scope.trustSrcurl = function(data) 
{
    return $sce.trustAsResourceUrl(data);
}

Htmlページに

<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{trustSrcurl(video.src)}}" allowfullscreen frameborder="0"></iframe>
4

私はVideogularを使って同じ問題に遭遇しました。 ng-srcを使うと以下のようになりました。

Error: [$interpolate:interr] Can't interpolate: {{url}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy

私は基本的なディレクティブを書くことで問題を修正しました:

angular.module('app').directive('dynamicUrl', function () {
return {
  restrict: 'A',
  link: function postLink(scope, element, attrs) {
    element.attr('src', scope.content.fullUrl);
  }
};
});

HTML:

 <div videogular vg-width="200" vg-height="300" vg-theme="config.theme">
    <video class='videoPlayer' controls preload='none'>
          <source dynamic-url src='' type='{{ content.mimeType }}'>
    </video>
 </div>
2
cagan

誰かがTypeScriptソリューションを探しているなら:

.tsファイル(該当する場合は変数を変更します):

module App.Filters {

    export class trustedResource {

        static $inject:string[] = ['$sce'];

        static filter($sce:ng.ISCEService) {
            return (value) => {
                return $sce.trustAsResourceUrl(value)
            };
        }
    }
}
filters.filter('trustedResource', App.Filters.trusted.filter);

Html:

<video controls ng-if="HeaderVideoUrl != null">
  <source ng-src="{{HeaderVideoUrl | trustedResource}}" type="video/mp4"/>
</video>
2
GONeale

エラーメッセージに基づくと、あなたの問題は補間(通常は式{{}})に関連しているようで、クロスドメインの問題ではないようです。基本的にng-src="{{object.src}}"は吸います。

ng-srcはIMOを念頭に置いてimgタグを使用して設計されました。 <source>には不適切かもしれません。 http://docs.angularjs.org/api/ng.directive:ngSrc を参照してください。

あなたが<source src="somesite.com/myvideo.mp4"; type="video/mp4"/>を宣言すれば、それはうまくいくでしょうね。 (私はsrcのためにng-srcを削除していることに注意してください。)そうでない場合は最初に修正しなければなりません。

それから{{object.src}}が期待値を返すことを確認してください(outside of <video>):

<span>{{object.src}}</span>
<video>...</video>

期待値が返された場合は、次の文が機能するはずです。

<source src="{{object.src}}"; type="video/mp4"/> //src instead of ng-src
1
roland

testsでこのエラーが発生しました。ディレクティブtemplateUrlは信頼されていませんでしたが、仕様のみのため、テンプレートディレクトリを追加しました。

beforeEach(angular.mock.module('app.templates'));

私のメインディレクトリはappです。

0
ecoologic