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

我看见 这篇关于跨域问题的帖子但是我不知道如何解决这个问题或我应该采取什么方向。有什么想法吗?任何帮助表示赞赏


174
2018-01-22 19:25


起源


你也可以张贴你的corodva's config.xml 文件? - Andrew Shustariov
现在我还在浏览器中测试,所以我甚至没有开始我的phonegap调试。 - 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


252
2018-03-22 11:51



没有iFrame,这可能吗?我需要嵌入一个视频,其中会话信息确定是否允许消费者观看视频。会话信息不通过iFrame传送。 - Blake
是的,它可以做到。 - Amit Kumar Ghosh
很好,如果你可以使用iframe - Ringo
真棒!这也适用于Vimeo视频。 - haakon.io


另一个简单的解决方案是创建过滤器:

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>

255
2017-07-01 20:51



绝对是最优雅,最有棱角的解决方案。 - Sc0ttyD
为我工作,实际上它比使用iframe更好。 - Nadjib
最好的答案,更有棱角的精神,它在其他解决方案没有出于某些原因的情况下起作用。非常感谢! - floribon


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

66
2018-02-13 14:39



注意:如果 resourceUrlWhitelist 以某种方式不适合你,检查你是否在域名之后没有双斜线(在连接变量中的东西并且它们都有斜杠时很容易发生这种情况) - jakub.g
这是解决此问题的更清洁,全球性和安全的方法。 - DJ.
对于试图理解该问题的人来说,“拨出”并不是一个很好的术语。 - Ringo
谢谢@Ringo - 我已添加评论以澄清。 - superluminary


这里有同样的问题。我需要绑定到Youtube链接。什么对我有用,如 全球解决方案,是将以下内容添加到我的配置中:

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

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

}]);

添加 '自' 在那里很重要 - 否则将无法绑定到任何URL。来自 角文档

'self' - 特殊字符串'self'可用于匹配所有字符串   与使用相同域的应用程序文档相同的域的URL   协议。

有了这个,我现在能够直接绑定到任何Youtube链接。

您显然必须根据需要自定义正则表达式。希望能帮助到你!


20
2018-06-06 09:41





解决此问题的最佳和简单的解决方案是从控制器中的此功能传递数据。

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

3
2017-09-09 06:09





我使用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
2018-02-21 16:26





如果有人在寻找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
2018-03-17 02:17