$ sce.trustAsHtml(string)を使用して、Angular 1.2以降でng-bind-html-unsafeを複製する方法


226

ng-bind-html-unsafe Angular 1.2で削除されました

私は使用する必要がある場所に何かを実装しようとしていますng-bind-html-unsafe。ドキュメントとgithub commitで彼らは言う:

ng-bind-htmlは、$ sce.trustAsHtml(string)の結果にバインドされたときに、ng-html-bind-unsafeのような動作(innerHTMLのサニタイズなしの結果)を提供します。

これどうやってやるの?


回答:


245

それは:

<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]
 }]);

10
関数から返された値でこれをどのように行うことができますか?<p ng-bind-html = ""> {{description(category.id)}} </ p>
dasper 2013

2
私があなたを正しく理解しているかどうかはわかりませんが <p ng-bind-html="trustedHtml"></p> 、そして$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad '20

1
返信してくれてありがとう!どうやら問題は私が1.0.8を使用していたことです。動的なセクション数のフォームがあるので、変更時に適切な説明を表示したいと思いました。<p ng-bind-html="description(category.id)"></p>その後、関数の最後の行:return $sce.trustAsHtml(value);
dasper

2
しかし... var x = sce.trustAsHtml( 'foo'); var y = sce.trustAsHtml( 'foo'); x == y; false ...関数が新しいオブジェクトを返すので、これは無限のダイジェストループを作成すべきではありませんか?
rych

25
また、$
sceを

634

フィルタ

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

使用法

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

1
なぜngSanitizeここに必要なのですか?

2
$ sceサービスがngSanitizeで定義されているため、@ OliverJosephAsh。それらは主要な機能を分割したので、angularを少しだけ使用でき、必ずしもフレームワーク全体を使用する必要はありません。
Chris Sattinger 2014年

1
このようなもののセキュリティへの影響は何だろうと思っていましたか?別の質問さらに明確にするように求めました。すべての入力に感謝します!
フィリップブリー2014年

9
バージョン1.2の@felix(これが追加されたとき)は、コアではなくngSanitize、デフォルトで有効になっているため、必要はありませんngSanitize
TheSharpieOne

2
これは、角度のあるチームによって行われた設計上の決定です。つまり、フィルターを実装する方法です。そうしないと、フィルターは機能しません。これが関数を返さなければならない理由は、angularが「適切な瞬間を見つける」まで処理を遅らせる可能性があるためです。それ以外の場合、フレームワークはフィルターが呼び出されたときに影響を与えません。それは良い面と悪い面の両方ですが、私が知る限り、角度のトリッキーな処理に対処する必要があります。詳細はこちら:docs.angularjs.org/api/ng/provider/$filterProvider
Chris

16

個人的には、データベースに入る前にすべてのデータをいくつかの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);
}]);

2つの例の違いは不明です。チームメンバーの1人がSystem.out.println(&ldquo; Hello World!&rdquo;);を使用している場合に問題が発生します。データベース内。彼女は<div data-ng-bind-html = "text"> </ div>を使用しており、ページにSystem.out.println(&ldquo; Hello World!&rdquo;);として表示されます。ngBindHtmlUnsafeディレクティブを使用すると、この問題が解決すると言っていますか?
Alan2 2013年

@Alan <script>System.out.printIn("Hello World!");</script>私のPHPがユーザー入力からすべてのJSを削除したので、個人的にこれを試していない場合は、うまくいくと思います。私の2番目の例を削除したのは、Angularのネイティブの例がすべての点で優れているためです。
Michael J. Calkins 2013年

サマーノートエディターでこれを行う方法、最初にサーバーからjsonデータ(htmlを含む)を取得します。サマーノートでは、ng-modelを使用しています。信頼できるようにコードをサマーノートエディターに表示する方法
codelearner

8

var line = "<label onclick="alert(1)">aaa</label>";

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>

ngSanitizeルートアングルアプリに追加

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

(html)を使用:

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

サマーノートエディターでこれを行う方法、最初にサーバーからjsonデータ(htmlを含む)を取得します。サマーノートでは、ng-modelを使用しています。信頼できるようにコードをサマーノートエディターに表示する方法
codelearner

7

フィルターを作成するだけでうまくいきます。(Angle 1.6で回答)

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

そして、これをhtmlで次のように使用します。

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

これは醜いエラーを修正します: "不明なプロバイダー:eProvider <-e <-unsafeFilter"
Valera

3

古いディレクティブを元に戻したい場合は、これをアプリに追加できます。

指令:

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>

ソース-https://github.com/angular-ui/bootstrap/issues/813


同じように動作しません。
ケーシー

サマーノートエディターでこれを行う方法、最初にサーバーからjsonデータ(htmlを含む)を取得します。サマーノートでは、ng-modelを使用しています。信頼できるようにコードをサマーノートエディターに表示する方法
codelearner

3

JavaScript

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

HTML

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

サマーノートエディターでこれを行う方法、最初にサーバーからjsonデータ(htmlを含む)を取得します。サマーノートでは、ng-modelを使用しています。信頼できるようにコードをサマーノートエディターに表示する方法
codelearner

1

以下のためのRailsを使用している場合は(少なくとも私の場合)angularjs-レール宝石を、サニタイズモジュールを追加することを忘れないでください。

//= 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 '';
}

サマーノートエディターでこれを行う方法、最初にサーバーからjsonデータ(htmlを含む)を取得します。サマーノートでは、ng-modelを使用しています。信頼できるようにコードをサマーノートエディターに表示する方法
codelearner

このアウトをチェックしてください:github.com/summernote/summernote/issues/...
SomeDudeSomewhere

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

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

3
回答としてコードだけを投稿するのではなく、コードの機能と質問の問題を解決する方法の説明も含めてください。説明付きの回答は一般に質が高く、賛成票を集める可能性が高くなります。
Mark Rotteveel、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.