คุณใช้ $ sce.trustAsHtml (สตริง) เพื่อทำซ้ำ ng-bind-html-unsafe ใน Angular 1.2+ อย่างไร


226

ng-bind-html-unsafe ถูกลบใน Angular 1.2

ng-bind-html-unsafeฉันพยายามที่จะดำเนินการบางสิ่งบางอย่างที่ฉันจำเป็นต้องใช้ ในเอกสารและ GitHub กระทำพวกเขาพูดว่า:

ng-bind-html ให้ ng-html-bind-unsafe เช่นพฤติกรรม (innerHTML ของผลลัพธ์โดยไม่มีการฆ่าเชื้อ) เมื่อถูกผูกไว้กับผลลัพธ์ของ $ sce.trustAsHtml (สตริง)

คุณจะทำสิ่งนี้ได้อย่างไร


คำตอบ:


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

2
ไม่แน่ใจว่าฉันทำให้คุณถูกต้อง แต่: <p ng-bind-html="trustedHtml"></p> และ$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad

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 ต้องถูกส่งผ่านไปยังคอนโทรลเลอร์หรือคุณไม่ได้รับ $
sce

633

กรอง

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

การใช้

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

1
ทำไมคุณถึงต้องการngSanitizeที่นี่?

2
@OliverJosephAsh เนื่องจากบริการ $ sce ถูกกำหนดใน ngSanitize มันแยกการทำงานหลัก ๆ ออกไปเพื่อให้เราสามารถใช้เชิงมุมได้เพียงเล็กน้อยและไม่จำเป็นต้องใช้กรอบทั้งหมด
Chris Sattinger

1
ฉันสงสัยว่าสิ่งที่เกี่ยวข้องกับความปลอดภัยของสิ่งนี้อาจเป็นอย่างไร ฉันถามการชี้แจงเพิ่มเติมในคำถามที่แยกต่างหาก การป้อนข้อมูลทั้งหมดชื่นชม!
Philip Bulley

9
@felix ในรุ่น 1.2 (เมื่อพวกเขาเพิ่มสิ่งนี้) มันถูกเปิดใช้งานโดยค่าเริ่มต้นเป็นส่วนหนึ่งของ core ไม่ใช่ngSanitizeดังนั้นจึงไม่จำเป็นต้องngSanitize
TheSharpieOne

2
นี่คือการตัดสินใจออกแบบโดยทีมงานเชิงมุม - นั่นคือวิธีการใช้งานตัวกรอง - ถ้าคุณทำอย่างอื่นตัวกรองจะไม่ทำงาน เหตุผลที่สิ่งนี้ต้องส่งคืนฟังก์ชันคือมุมเชิงมุมสามารถชะลอการประมวลผลจนกว่าจะพบช่วงเวลาที่เหมาะสม มิฉะนั้นเฟรมเวิร์กจะไม่มีอิทธิพลใด ๆ เมื่อเรียกตัวกรอง ทั้งดีและไม่ดี แต่เท่าที่ฉันสามารถบอกได้ - มันจำเป็นที่จะต้องจัดการกับการประมวลผลที่ซับซ้อนของแองกูลาร์ ข้อมูลเพิ่มเติมที่นี่: 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);
}]);

ฉันไม่ชัดเจนว่าความแตกต่างระหว่างสองตัวอย่างคืออะไร หนึ่งในสมาชิกในทีมของเรามีปัญหาที่พวกเขามี System.out.println (& ldquo; Hello World! & rdquo;); ในฐานข้อมูล เธอใช้ <div data-ng-bind-html = "text"> </div> และมันปรากฏบนหน้าเว็บเป็น: System.out.println (& ldquo; Hello World! & rdquo;); คุณกำลังบอกว่าการใช้ ngBindHtmlUnsafe ของคุณจะแก้ไขปัญหานี้ได้หรือไม่
Alan2

@ อลันฉันเชื่อว่ามันจะใช้งานได้ถ้า<script>System.out.printIn("Hello World!");</script>ยังไม่ได้ลองทำสิ่งนี้เป็นการส่วนตัวเพราะ PHP ของฉันลบ JS ทั้งหมดออกจากการป้อนข้อมูลผู้ใช้ ฉันลบตัวอย่างที่สองของฉันเพราะคนพื้นเมืองของแองกูลาร์นั้นยอดเยี่ยมในทุก ๆ ทางแค่ใช้อันนั้น
Michael J. Calkins

วิธีการทำเช่นนี้สำหรับ Summernote Editor ตอนแรกฉันจะได้รับข้อมูล json (ซึ่งมี html) จากเซิร์ฟเวอร์ใน summernote ฉันใช้ ng-model วิธีการสร้างรหัสที่เชื่อถือได้เพื่อแสดงในตัวแก้ไข
ฤดูร้อน

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

วิธีการทำเช่นนี้สำหรับ Summernote Editor ตอนแรกฉันจะได้รับข้อมูล json (ซึ่งมี html) จากเซิร์ฟเวอร์ใน summernote ฉันใช้ ng-model วิธีการสร้างรหัสที่เชื่อถือได้เพื่อแสดงในตัวแก้ไข
ฤดูร้อน

7

เพียงสร้างตัวกรองจะทำเคล็ดลับ (ตอบสำหรับ 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: "ผู้ให้บริการที่ไม่รู้จัก: eProvider <- e <- unsafeFilter"
Valera Tumash

3

หากคุณต้องการคำสั่งเก่าคุณสามารถเพิ่มสิ่งนี้ลงในแอพของคุณ:

Directive:

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


ไม่ทำตัวเหมือนกัน
Casey

วิธีการทำเช่นนี้สำหรับ Summernote Editor ตอนแรกฉันจะได้รับข้อมูล json (ซึ่งมี html) จากเซิร์ฟเวอร์ใน summernote ฉันใช้ ng-model วิธีการสร้างรหัสที่เชื่อถือได้เพื่อแสดงในตัวแก้ไข
ฤดูร้อน

3

JavaScript

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

HTML

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

วิธีการทำเช่นนี้สำหรับ Summernote Editor ตอนแรกฉันจะได้รับข้อมูล json (ซึ่งมี html) จากเซิร์ฟเวอร์ใน summernote ฉันใช้ ng-model วิธีการสร้างรหัสที่เชื่อถือได้เพื่อแสดงในตัวแก้ไข
ฤดูร้อน

1

สำหรับRails (อย่างน้อยในกรณีของฉัน) ถ้าคุณใช้อัญมณี angularjs-railsโปรดอย่าลืมเพิ่มโมดูล sanitize

//= 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 Editor ตอนแรกฉันจะได้รับข้อมูล json (ซึ่งมี html) จากเซิร์ฟเวอร์ใน summernote ฉันใช้ ng-model วิธีการสร้างรหัสที่เชื่อถือได้เพื่อแสดงในตัวแก้ไข
ฤดูร้อน


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.