Angular:我可以完全禁用消毒吗?

时间:2015-06-08 14:53:30

标签: javascript angularjs

是否可以完全禁用HTML的清理?

我想要实现的是拥有我的控制器:

$scope.greeting = '<h2>Hello World</h2>'

在我看来

{{greeting}}

我不能(也不想)使用ng-bind-html等,我想要一起禁用消毒。

只是为了给出一些更多的背景 - 我正在准备简单的#34;框架环绕&#34;用于为特定系统开发模板。

为此系统开发模板时,他们会预先定义一些代码段,您可以通过编写&#34; {{something}}&#34;但它没有在角度上运行(可能是胡子或其他东西)。

现在模板只能在线开发,并且它是非常用户不友好的过程。因此我设置了角度与相应路线等的简单项目,因此每个人都可以在他们的机器上开发模板,然后将其复制到系统中。

这就是为什么在模板文件中它不应该以角度来完成它,它只是尽可能地接近它们的系统。

最后一点 - 我确实尝试过:

myApp.config(['$sceProvider',function($sceProvider){
    $sceProvider.enabled(false);
}]);

我没有为我做任何事

4 个答案:

答案 0 :(得分:7)

是的,您可以关闭SCE,但这不会导致您的字符串被插入HTML

使用您的方案:

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

直接插入标题而不使用ng-bind-html="movie.title"

<p>{{movie.title}}</p>

会产生这个

<h1>Egghead.io AngularJS Binding</h1>

直接插值似乎已经消毒,但实际上并未编译。

除非在指令中编译,否则带有 HTML 的插值字符串将被视为字符串。

其他框架往往是“基于字符串”(它们直接提供浏览器),而 AngularJS 是“基于DOM”,它编译 HTML 并积极管理它与范围和观看事件。 Martin Fowler将此称为模板 View vs Transform View

HTML可以在Directives中编译,但只能在标记和控制器中进行插值

我创建了2个试图访问“不安全网址”的掠夺者,这意味着我在ng-src内插了一个网址而不使用$sce.trustAs

图1:Plunker 1 在配置期间停用SCE

标记插入“不安全的网址”:

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

应用停用$sceProvider

var app = angular.module('plunker', ['ngSanitize']);
app.config(['$sceProvider',function($sceProvider){
    $sceProvider.enabled(false);
}]);
app.controller('MainCtrl', function($scope, $sce) {

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

插入“不安全”URL而不会出错。显示视频。

图表2:Plunker 2 app.config注释掉了,使用默认SCE设置

var app = angular.module('plunker', ['ngSanitize']);
//app.config(['$sceProvider',function($sceProvider){
//    $sceProvider.enabled(false);
//}]);
app.controller('MainCtrl', function($scope, $sce) {

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

错误:

  

错误:[$ interpolate:interr]无法插值:{{movie.src}}错误:   [$ sce:insecurl]阻止从url加载资源   $ sceDelegate政策。网址:http://www.youtube.com/embed/Lx7ycjC8qjE

答案 1 :(得分:1)

前段时间我设法渲染了一些从这样的服务返回的HTML:

$scope.greeting = $sce.trustAsHtml('<h2>Hello World</h2>');

并在您的HTML中

<div ng-bind-html="htmlGreeting"></div>

不要忘记在控制器中注入$ sce服务。

编辑在这里是一个小例子:https://jsfiddle.net/b78hkssn/2/

答案 2 :(得分:0)

尝试使用装饰器增强或更改$ sce的标准行为:

RevokeDragDrop

答案 3 :(得分:-1)

我设法找到另一种解决问题的方法,而不使用任何指令。

基本上我使用注入器来使用$ compile服务。

JS:

angular.injector(['ng']).invoke(function($compile, $rootScope) {
    $('.html-content').append($compile('<h2>Hello World</h2>')($rootScope));
});

这是一个演示:https://jsfiddle.net/davguij/tby59sk7/1/