Bagaimana Anda menggunakan $ sce.trustAsHtml (string) untuk mereplikasi ng-bind-html-tidak aman di Angular 1.2+

226

ng-bind-html-unsafe dihapus di Angular 1.2

Saya mencoba menerapkan sesuatu yang perlu saya gunakan ng-bind-html-unsafe. Dalam dokumen dan pada komitmen github mereka mengatakan:

ng-bind-html menyediakan perilaku seperti ng-html-bind-tidak aman (innerHTML hasilnya tanpa sanitasi) ketika terikat dengan hasil $ sce.trustAsHtml (string).

Bagaimana kamu melakukan ini?

timhaak
sumber

Jawaban:

245

Itu harus:

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

plus di controller Anda:

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

alih-alih sintaks lama, tempat Anda dapat mereferensikan $scope.htmlvariabel secara langsung:

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

Seperti yang ditunjukkan beberapa komentator, $sceharus disuntikkan ke controller, jika tidak Anda akan mendapatkan $sce undefinedkesalahan.

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

 myApp.controller('MyController', ['$sce', function($sce) {
    // ... [your code]
 }]);
Nenad
sumber
10
Bagaimana Anda bisa melakukan ini dengan nilai yang dikembalikan oleh suatu fungsi? <p ng-bind-html = ""> {{description (category.id)}} </p>
dasper
2
Tidak yakin apakah saya benar, tetapi: <p ng-bind-html="trustedHtml"></p> dan$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad
1
Aku mencintaimu karena merespons! Rupanya masalahnya adalah saya menggunakan 1.0.8. Saya memiliki formulir dengan jumlah bagian dinamis sehingga saat perubahan saya ingin menampilkan deskripsi yang tepat. <p ng-bind-html="description(category.id)"></p>maka baris terakhir dari fungsi:return $sce.trustAsHtml(value);
dasper
2
Tapi ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); x == y; false ... Jadi, bukankah seharusnya ini menciptakan loop digest tak terhingga karena fungsi Anda mengembalikan objek baru?
rych
25
Juga layak disebutkan adalah $ sce perlu diteruskan ke controller atau Anda mendapatkan $ sce tidak didefinisikan
isimmons
634

Saring

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

Pemakaian

<ANY ng-bind-html="value | unsafe"></ANY>
Chris
sumber
1
Mengapa kamu perlu di ngSanitizesini?
2
@OliverJosephAsh karena layanan $ sce didefinisikan dalam ngSanitize. mereka memecah fungsionalitas utama sehingga kita dapat menggunakan sudut sedikit saja dan tidak selalu harus menggunakan seluruh kerangka kerja.
Chris Sattinger
1
Saya bertanya-tanya apa implikasi keamanan dari sesuatu seperti ini? Saya sudah meminta klarifikasi lebih lanjut dalam pertanyaan terpisah . Semua masukan dihargai!
Philip Bulley
9
@ Feliks dalam versi 1.2 (ketika mereka menambahkan ini) itu diaktifkan secara default sebagai bagian dari inti, tidak ngSanitize, jadi tidak perlu untukngSanitize
TheSharpieOne
2
Ini adalah keputusan desain yang dibuat oleh tim sudut - begitulah filter harus diimplementasikan - jika Anda melakukannya sebaliknya, mereka tidak akan berfungsi. Alasan mengapa ini harus mengembalikan fungsi adalah bahwa sudut dapat menunda pemrosesan sampai 'menemukan momen yang tepat'. Kalau tidak, kerangka kerja tidak akan memiliki pengaruh pada saat filter dipanggil. Itu baik dan buruk, tapi sejauh yang saya tahu - perlu untuk mengatasi proses rumit angulars. Info lebih lanjut di sini: docs.angularjs.org/api/ng/provider/$filterProvider
Chris
16

Secara pribadi saya membersihkan semua data saya dengan beberapa perpustakaan PHP sebelum masuk ke database sehingga tidak perlu filter XSS lain untuk saya.

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

Menggunakan:

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

Untuk menonaktifkan $sce:

app.config(['$sceProvider', function($sceProvider) {
    $sceProvider.enabled(false);
}]);
Michael J. Calkins
sumber
Saya tidak jelas apa perbedaan antara kedua contoh tersebut. Salah satu anggota tim kami memiliki masalah di mana mereka memiliki System.out.println (& ldquo; Hello World! & Rdquo;); dalam database. Dia menggunakan <div data-ng-bind-html = "text"> </div> dan muncul di halaman sebagai: System.out.println (& ldquo; Hello World! & Rdquo;) ;. Apakah Anda mengatakan bahwa menggunakan arahan ngBindHtmlUnsafe Anda akan memperbaiki masalah ini?
Alan2
@ Alan Saya yakin ini akan berfungsi jika ya <script>System.out.printIn("Hello World!");</script>, belum mencoba ini secara pribadi karena PHP saya menghapus semua JS dari input pengguna. Saya menghapus contoh kedua saya karena yang asli Angular lebih unggul dalam segala hal, gunakan saja yang itu.
Michael J. Calkins
Bagaimana melakukan ini untuk editor summernote, awalnya saya akan mendapatkan data json (yang berisi html) dari server, di summernote saya menggunakan ng-model. cara membuat kode sebagai tepercaya untuk ditampilkan di editor
summernote
8

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

1. gunakan filter

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

menggunakan (html):

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

2. gunakan ngSanitize: lebih aman

termasuk angular-sanitize.js

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

tambahkan ngSanitizedi aplikasi root angular

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

menggunakan (html):

<span ng-bind-html="line"></span>
==>click `aaa` nothing happen
nguyên
sumber
Bagaimana melakukan ini untuk editor summernote, awalnya saya akan mendapatkan data json (yang berisi html) dari server, di summernote saya menggunakan ng-model. cara membuat kode sebagai tepercaya untuk ditampilkan di editor
summernote
7

Cukup membuat filter akan melakukan triknya. (Dijawab untuk Sudut 1.6)

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

Dan gunakan ini sebagai ikuti di html.

<h2 ng-bind-html="someScopeValue | trustHtml"></h2>
BAJA
sumber
Yang ini memperbaiki kesalahan dengan uglifying: "Penyedia tidak dikenal: eProvider <- e <- unsafeFilter"
Valera Tumash
3

Jika Anda ingin arahan lama kembali, Anda dapat menambahkan ini ke aplikasi Anda:

Pengarahan:

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

Pemakaian

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

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

Adrian Enriquez
sumber
Tidak berperilaku sama.
Casey
Bagaimana melakukan ini untuk editor summernote, awalnya saya akan mendapatkan data json (yang berisi html) dari server, di summernote saya menggunakan ng-model. bagaimana membuat kode sebagai tepercaya untuk ditampilkan di editor
summernote
3

JavaScript

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

HTML

<pre ng-bind-html="get_pre(html)"></pre>
wcc526
sumber
Bagaimana melakukan ini untuk editor summernote, awalnya saya akan mendapatkan data json (yang berisi html) dari server, di summernote saya menggunakan ng-model. cara membuat kode sebagai tepercaya untuk ditampilkan di editor
summernote
1

Untuk Rails (setidaknya dalam kasus saya) jika Anda menggunakan permata angularjs-rails , harap diingat untuk menambahkan modul sanitasi

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

Dan kemudian memuatnya di aplikasi Anda ...

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

Maka Anda dapat melakukan hal berikut:

Pada templat:

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

Dan akhirnya:

$scope.phone_with_break = function (x) {
  if (x.phone != "") {
   return x.phone + "<br>";
  }
  return '';
}
SomeDudeSomewhere
sumber
Bagaimana melakukan ini untuk editor summernote, awalnya saya akan mendapatkan data json (yang berisi html) dari server, di summernote saya menggunakan ng-model. bagaimana membuat kode sebagai tepercaya untuk ditampilkan di editor
summernote
Lihat ini: 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>
Saurabh
sumber
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>
Surya Pratim Mukherjee
sumber
3
Tolong jangan posting kode hanya sebagai jawaban, tetapi juga sertakan penjelasan apa yang kode Anda lakukan dan bagaimana memecahkan masalah pertanyaan. Jawaban dengan penjelasan umumnya berkualitas lebih tinggi, dan lebih cenderung menarik upvotes.
Mark Rotteveel