【问题标题】:How do you use $sce.trustAsHtml(string) to replicate ng-bind-html-unsafe in Angular 1.2+您如何使用 $sce.trustAsHtml(string) 在 Angular 1.2+ 中复制 ng-bind-html-unsafe
【发布时间】:2013-08-22 20:20:55
【问题描述】:

ng-bind-html-unsafe 在 Angular 1.2 中被删除

我正在尝试实现一些我需要使用ng-bind-html-unsafe 的东西。在文档和 github 提交中,他们说:

ng-bind-html 提供类似 ng-html-bind-unsafe 的行为(innerHTML 的结果没有 sanitization) 绑定到 $sce.trustAsHtml(string) 的结果时。

你是怎么做到的?

【问题讨论】:

标签: angularjs


【解决方案1】:
$scope.trustAsHtml=function(scope)
{
    return $sce.trustAsHtml(scope);
}
<p class="card-text w-100" ng-bind-html="trustAsHtml(note.redoq_csd_product_lead_note)"></p>

【讨论】:

  • 请不要只发布代码作为答案,还要说明您的代码的作用以及它如何解决问题的问题。带有解释的答案通常质量更高,更有可能吸引投票。
【解决方案2】:
my helpful code for others(just one aspx to do text area post)::

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication45.WebForm1" %>

<!DOCTYPE html>

    enter code here

<html ng-app="htmldoc" xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="angular.min.js"></script>
    <script src="angular-sanitize.min.js"></script>
    <script>
        angular.module('htmldoc', ['ngSanitize']).controller('x', function ($scope, $sce) {
            //$scope.htmlContent = '<script> (function () { location = \"http://moneycontrol.com\"; } )()<\/script> In last valid content';
            $scope.htmlContent = '';
            $scope.withoutSanitize = function () {
                return $sce.getTrustedHtml($scope.htmlContent);
            };
            $scope.postMessage = function () {
                var ValidContent = $sce.trustAsHtml($scope.htmlContent);

                //your ajax call here
            };
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
        Example to show posting valid content to server with two way binding
        <div ng-controller="x">
            <p ng-bind-html="htmlContent"></p>
            <textarea ng-model="htmlContent" ng-trim="false"></textarea>
            <button ng-click="postMessage()">Send</button>
        </div>
    </form>
</body>
</html>

【讨论】:

    【解决方案3】:

    只需创建一个过滤器就可以了。 (针对 Angular 1.6 回答)

    .filter('trustHtml', [
            '$sce',
            function($sce) {
                return function(value) {
                    return $sce.trustAs('html', value);
                }
            }
        ]);
    

    并在 html 中按如下方式使用。

    <h2 ng-bind-html="someScopeValue | trustHtml"></h2>
    

    【讨论】:

    • 这个修复了 uglifying 的错误:“Unknown provider: eProvider
    【解决方案4】:

    应该是:

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

    加在你的控制器中:

    $scope.html = '<ul><li>render me please</li></ul>';
    $scope.trustedHtml = $sce.trustAsHtml($scope.html);
    

    代替旧语法,您可以直接引用$scope.html 变量:

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

    正如几位评论者指出的,$sce 必须注入到控制器中,否则会出现$sce undefined 错误。

     var myApp = angular.module('myApp',[]);
    
     myApp.controller('MyController', ['$sce', function($sce) {
        // ... [your code]
     }]);
    

    【讨论】:

    • 如何使用函数返回的值来做到这一点?

      {{description(category.id)}}

    • 不确定我是否正确,但是:&lt;p ng-bind-html="trustedHtml"&gt;&lt;/p&gt;$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
    • 我爱你的回应!显然问题是我使用 1.0.8。我有一个包含动态部分的表格,所以我想显示正确的描述。 &lt;p ng-bind-html="description(category.id)"&gt;&lt;/p&gt; 然后函数的最后一行:return $sce.trustAsHtml(value);
    • 但是... var x = sce.trustAsHtml('foo'); var y = sce.trustAsHtml('foo'); x==y; false ...因此,由于您的函数返回一个新对象,这不应该创建一个无限摘要循环吗?
    • 另外值得一提的是 $sce 需要传入控制器,否则你会得到 $sce is not defined
    【解决方案5】:

    我个人在进入数据库之前会使用一些 PHP 库对所有数据进行清理,因此我不需要另一个 XSS 过滤器。

    来自 AngularJS 1.0.8

    directives.directive('ngBindHtmlUnsafe', [function() {
        return function(scope, element, attr) {
            element.addClass('ng-binding').data('$binding', attr.ngBindHtmlUnsafe);
            scope.$watch(attr.ngBindHtmlUnsafe, function ngBindHtmlUnsafeWatchAction(value) {
                element.html(value || '');
            });
        }
    }]);
    

    使用方法:

    <div ng-bind-html-unsafe="group.description"></div>
    

    禁用$sce

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

    【讨论】:

    • 我不清楚这两个例子有什么区别。我们的一位团队成员遇到了 System.out.println(“Hello World!”); 的问题。在数据库中。她正在使用
      ,它在页面上显示为:System.out.println(“Hello World!”);。你是说使用你的 ngBindHtmlUnsafe 指令可以解决这个问题吗?
    • @Alan 我相信如果它是&lt;script&gt;System.out.printIn("Hello World!");&lt;/script&gt; 会起作用,我没有亲自尝试过,因为我的 PHP 从用户输入中删除了所有 JS。我删除了我的第二个示例,因为 Angular 的原生示例在各方面都非常出色,只需使用该示例即可。
    • 如何为summernote编辑器执行此操作,最初我将从服务器获取json数据(包含html),在summernote中我使用的是ng-model。如何使代码可信地显示在summernote编辑器中
    【解决方案6】:

    var line = "&lt;label onclick="alert(1)"&gt;aaa&lt;/label&gt;";

    1。使用过滤器

    app.filter('unsafe', function($sce) { return $sce.trustAsHtml; });
    

    使用(html):

    <span ng-bind-html="line | unsafe"></span>
    ==>click `aaa` show alert box
    

    2。使用 ngSanitize :更安全

    包括angular-sanitize.js

    <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
    

    在根 Angular 应用中添加 ngSanitize

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

    使用(html):

    <span ng-bind-html="line"></span>
    ==>click `aaa` nothing happen
    

    【讨论】:

    • 如何为summernote编辑器执行此操作,最初我将从服务器获取json数据(包含html),在summernote中我使用的是ng-model。如何使代码可信地显示在summernote编辑器中
    【解决方案7】:

    JavaScript

    $scope.get_pre = function(x) {
        return $sce.trustAsHtml(x);
    };
    

    HTML

    <pre ng-bind-html="get_pre(html)"></pre>
    

    【讨论】:

    • 如何为summernote编辑器执行此操作,最初我将从服务器获取json数据(包含html),在summernote中我使用的是ng-model。如何使代码可信地显示在summernote编辑器中
    【解决方案8】:

    对于 Rails(至少在我的情况下),如果您使用 angularjs-rails gem,请记得添加清理模块

    //= require angular
    //= require angular-sanitize
    

    然后将其加载到您的应用中...

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

    然后您可以执行以下操作:

    在模板上:

    %span{"ng-bind-html"=>"phone_with_break(x)"}
    

    最终:

    $scope.phone_with_break = function (x) {
      if (x.phone != "") {
       return x.phone + "<br>";
      }
      return '';
    }
    

    【讨论】:

    • 如何为summernote编辑器执行此操作,最初我将从服务器获取json数据(包含html),在summernote中我使用的是ng-model。如何使代码可信地显示在summernote编辑器中
    【解决方案9】:

    过滤器

    app.filter('unsafe', function($sce) { return $sce.trustAsHtml; });
    

    用法

    <ANY ng-bind-html="value | unsafe"></ANY>
    

    【讨论】:

    • 这里为什么需要ngSanitize
    • @OliverJosephAsh 因为 $sce 服务是在 ngSanitize 中定义的。它们分解了主要功能,因此我们可以稍微使用 Angular,而不必总是使用整个框架。
    • 我一直想知道这样的安全隐患是什么?我已在a separate question 中要求更多说明。感谢所有输入!
    • @felix 在 1.2 版中(当他们添加这个时)默认情况下它作为核心的一部分启用,而不是ngSanitize,因此不需要ngSanitize
    • 这是 Angular 团队做出的设计决定 - 这就是过滤器的实现方式 - 如果你不这样做,它们将无法工作。这必须返回一个函数的原因是角度可以延迟处理,直到它“找到合适的时刻”。否则框架不会对何时调用过滤器产生任何影响。这既好又坏,但据我所知 - 有必要应对 angulars 的棘手处理。更多信息在这里:docs.angularjs.org/api/ng/provider/$filterProvider
    【解决方案10】:

    如果您想恢复旧指令,可以将其添加到您的应用中:

    指令:

    directives.directive('ngBindHtmlUnsafe', ['$sce', function($sce){
        return {
            scope: {
                ngBindHtmlUnsafe: '=',
            },
            template: "<div ng-bind-html='trustedHtml'></div>",
            link: function($scope, iElm, iAttrs, controller) {
                $scope.updateView = function() {
                    $scope.trustedHtml = $sce.trustAsHtml($scope.ngBindHtmlUnsafe);
                }
    
                $scope.$watch('ngBindHtmlUnsafe', function(newVal, oldVal) {
                    $scope.updateView(newVal);
                });
            }
        };
    }]);
    

    用法

    <div ng-bind-html-unsafe="group.description"></div>
    

    Source - https://github.com/angular-ui/bootstrap/issues/813

    【讨论】:

    • 行为不一样。
    • 如何为summernote编辑器执行此操作,最初我将从服务器获取json数据(包含html),在summernote中我使用的是ng-model。如何使代码可信地显示在summernote编辑器中
    猜你喜欢
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2013-06-18
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多