AngularJs 未加载外部资源

Posted

技术标签:

【中文标题】AngularJs 未加载外部资源【英文标题】:External resource not being loaded by AngularJs 【发布时间】:2014-02-13 01:16:29 【问题描述】:

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

我看到了this post about cross domain issues,但我不确定如何解决这个问题或我应该往哪个方向发展。有什么想法吗?任何帮助表示赞赏

【问题讨论】:

你能把你的corodva的config.xml文件也贴出来吗? 现在我还在浏览器中测试所以我还没有开始我的phonegap调试。 【参考方案1】:

这是唯一对我有用的解决方案:

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"  
        ng-src="trustSrc(movie.src)" allowfullscreen frameborder="0">
</iframe>

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

【讨论】:

如果没有 iFrame 这可能吗?我需要嵌入一个视频,其中会话信息确定是否允许消费者观看视频。会话信息不通过 iFrame 携带。 很好,如果你可以使用 iframe【参考方案2】:

我在 tests 中遇到了这个错误,指令 templateUrl 不受信任,但仅限于规范,所以我添加了模板目录:

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

我的主目录是app

【讨论】:

【参考方案3】:

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

【讨论】:

注意:如果 resourceUrlWhitelist 对您不起作用,请检查域名后是否没有双斜杠(当连接变量中的内容并且它们都有斜杠时很容易发生这种情况) 这是解决此问题的更清洁、全局和安全的方法。 “拨出”对于试图理解问题的人来说不是一个好词。 谢谢@Ringo - 我添加了一条评论来澄清。【参考方案4】:

如果有人正在寻找 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>

【讨论】:

【参考方案5】:

解决此问题的最佳且最简单的解决方案是在控制器中通过此函数传递您的数据。

$scope.trustSrcurl = function(data) 

    return $sce.trustAsResourceUrl(data);

在html页面中

<iframe class="youtube-player" type="text/html"   ng-src="trustSrcurl(video.src)" allowfullscreen frameborder="0"></iframe>

【讨论】:

【参考方案6】:

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

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>

【讨论】:

绝对是最优雅和最有棱角的解决方案。 为我工作,确实比使用 iframe 更好。 最佳答案,更有棱角的精神,它在其他解决方案因某些原因没有的地方起作用。非常感谢!【参考方案7】:

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

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

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

]);

在其中添加 'self' 很重要 - 否则将无法绑定到任何 URL。来自angular docs

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

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

您显然必须根据自己的需要自定义正则表达式。希望对您有所帮助!

【讨论】:

【参考方案8】:

我在使用 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- vg- vg-theme="config.theme">
    <video class='videoPlayer' controls preload='none'>
          <source dynamic-url src='' type=' content.mimeType '>
    </video>
 </div>

【讨论】:

【参考方案9】:

根据错误消息,您的问题似乎与 interpolation(通常是您的表达式 )有关,而不是与跨域问题有关。基本上ng-src="object.src" 很烂。

ng-src 在设计时考虑了 IMO 的 img 标签。它可能不适合&lt;source&gt;。见http://docs.angularjs.org/api/ng.directive:ngSrc

如果您声明&lt;source src="somesite.com/myvideo.mp4"; type="video/mp4"/&gt;,它将起作用,对吗? (请注意,我删除了ng-src 以支持src)如果不是,则必须先修复它。

然后确保object.src返回预期值(outside of &lt;video&gt;):

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

如果它返回预期值,则以下语句应该有效:

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

【讨论】:

只使用 src 并对 url 进行硬编码,一切都按我的意愿工作。一旦我使用 object.src 虽然 src 属性甚至没有被考虑过。我继续,甚至删除了源标签并将 src 与视频标签内联,但仍然没有 我的意思是你确定 object.src 返回一个值吗?它可能会返回 undefined。 object.src 正在返回一个值。使用

对其进行了测试 可能不得不这样做,已经找到了,看起来还不错。 videogular.com/#。感谢您的帮助 这与ng-src 被破坏无关(它没有被破坏)。它与 AngularJS 的安全策略有关:docs.angularjs.org/api/ng/service/$sce

以上是关于AngularJs 未加载外部资源的主要内容,如果未能解决你的问题,请参考以下文章

如果 iframe 无法在 src 加载资源,如何显示替代图像?使用 AngularJs?

AngularJS - 基于路由动态加载外部 JS

需要 angularjs-dragula 包时未加载 angularjs 指令

如何将 angularJs 用于动态创建的 HTML(未加载到 DOM)

AngularJS:使用ngRoute路由时未加载组件控制器

AngularJS + Django:URL 刷新或直接访问未正确加载