AngularJsによってロードされていない外部リソース


195

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):/);

クロスドメインの問題に関するこの投稿を見ましたが、これを解決する方法やどの方向に進むべきかわかりません。何かアイデアはありますか?どんな助けでもありがたいです


1
corodvaのconfig.xmlファイルも投稿できますか?
Andrew Shustariov 2014年

1
現在、私はまだブラウザーでテストしているので、電話ギャップのデバッグも開始していません。
mhartington 2014年

回答:


267

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

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">
</iframe>

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


これはiFrameなしで可能ですか?セッション情報がコンシューマーにビデオの視聴を許可するかどうかを決定するビデオを埋め込む必要があります。セッション情報はiFrameを介して伝達されません。
Blake

いいですね、iframeが使えるなら
Ringo

270

もう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>

22
間違いなく最もエレガントで角張ったソリューションです。
Sc0ttyD 2014

1
私にとってはうまくいきました。実際、iframeを使用するよりも優れています。
Thomas Amar

1
ベストアンサー、より鋭い精神、そしてそれは他の解決策が何らかの理由でしなかったところで機能しました。どうもありがとう!
floribon 2014年

76

$ 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(['**']);
});

2
注:resourceUrlWhitelistどういうわけか機能しない場合は、ドメイン名の後にダブルスラッシュがないかどうかを確認してください(変数からのものを連結するときにこれが起こりやすく、両方にスラッシュがある)
jakub.g

2
これは、この問題を回避するためのよりクリーンでグローバルで安全な方法です。
DJ。

「ダイヤルアウト」は、問題を理解しようとしている人にとっては良い言葉ではありません。
Ringo

1
ありがとう@Ringo-明確にするためにコメントを追加しました。
超夜明け2017年

21

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

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

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

}]);

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

'self'-特別な文字列 'self'を使用して、同じプロトコルを使用するアプリケーションドキュメントと同じドメインのすべてのURLと照合できます。

これで、YouTubeリンクに直接バインドできます。

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


4

この問題を解決するための最善かつ簡単なソリューションは、コントローラーのこの関数からデータを渡すことです。

$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>

2

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

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>

1

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

ng-srcimgタグを念頭に置いて設計されたIMO。には適切でない場合があります<source>http://docs.angularjs.org/api/ng.directive:ngSrcを参照してください

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

その確保{{object.src}}戻りを期待値(外部のを<video>)。

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

期待値を返す場合は、次のステートメントが機能しているはずです。

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

srcとURLのハードコーディングだけを使用すると、すべてが思い通りに機能します。{{object.src}}を使用するとすぐに、src属性は考慮されていません。私は先に進んで、ソースタグを削除し、srcをビデオタグとインラインにしましたが、何もしませんでした
mhartington

つまり、{{object.src}}が値を返すことを確信していますか?未定義を返す場合があります。
ローランド2014年

{{object.src}}が値を返しています。<p> </ p>と<a> </a>を使用してテストした
mhartington 2014年

1
おそらくそうする必要がありますが、すでにこれを見つけて、それはかなりよさそうです。videogular.com/#。助けてくれてありがとう
mhartington 2014年

2
これはng-src壊れていることとは関係ありません(壊れていません)。これは、AngularJSのセキュリティポリシーに関係しています:docs.angularjs.org/api/ng/service/$sce
Pauan

0

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.