AngularJS denetleyicisinden görünüme HTML ekleme


800

Bir AngularJS denetleyicisinde bir HTML parçası oluşturmak ve bu HTML'nin görünümde gösterilmesi mümkün müdür ?

Bu, tutarsız bir JSON blobunu iç içe bir id: valueçiftler listesine dönüştürme gereksiniminden gelir . Bu nedenle HTML denetleyicide oluşturulur ve şimdi görüntülemek için arıyorum.

Bir model özelliği oluşturdum, ancak yalnızca HTML'yi yazdırmadan görünümde bunu oluşturamıyorum .


Güncelleme

Sorunun, oluşturulan HTML'yi tırnak içinde dize olarak açısal oluşturmasından kaynaklandığı görülmektedir. Bu konuda bir yol bulmaya çalışır.

Örnek kontrolör:

var SomeController = function () {

    this.customHtml = '<ul><li>render me please</li></ul>';
}

Örnek görünüm:

<div ng:bind="customHtml"></div>

Verir:

<div>
    "<ul><li>render me please</li></ul>"
</div>

1
Ayrıca , eklenen HTML'de komut dosyalarını çalıştırmak için mümkün olup olmadığını soran bu soruya bakın .
kanun

Aynı ng-bağlayıcıya bağlı birden fazla nesne olabilir mi? `` ng-bind = "site.adresi_1 site.adresi_2 site.zip" gibi
fauverizm

Sayfanızda çok fazla şey varsa, angular.js'nin (delilik) 15046 satırını değiştirmeniz gerekecektir function htmlSanitizer(html) {.... Açısal geliştirici, html ONE SINGLE eksik parçasını bulmak için tüm sayfaların gizli öğelerini yavaş yavaş tek tek inceleyerek html ciltlerini bulabilmeniz gerektiğine karar verdi. !!! böyle bir varsayımda çok kızgın !!!
user3338098

Maalesef Luke tarafından seçilen cevap tam olarak doğru cevap olmayabilir. Doğru cevap burada başka bir soruda bulunabilir . Temel olarak, "ng-bind-html-unsafe içeriği yalnızca HTML olarak işler. Açılan kapsamı sonuçta ortaya çıkan DOM ile ilişkilendirmez. Bu amaçla $ compile hizmetini kullanmanız gerekir."
gm2008

ng-bind tüm dahili html'leri kaldırır. filtrenin çalışma şekli bu değil, filtre tek değer olduğunda sorun yok
Muhammad Umer

Yanıtlar:


1120

Açısal 1.x ng-bind-htmliçin HTML'de kullanın :

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

Bu noktada bir attempting to use an unsafe value in a safe contexthata alırsınız, bu nedenle bunu çözmek için ngSanitize veya $ sce kullanmanız gerekir .

$ sce

$sce.trustAsHtml()Html dizesini dönüştürmek için denetleyicide kullanın .

 $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);

ngSanitize

2 adım vardır:

  1. angular-sanitize.min.js kaynağını ekleyin, yani:
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. Bir js dosyasına (denetleyici veya genellikle app.js) ngSanitize ekleyin, yani:
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])


30
Açısal 1.2'de ng-bind-html-unsafekaldırıldı ve iki direktif birleştirildi. Bakınız: github.com/angular/angular.js/blob/master/…
Sasha Chedygov

60
NgSanitize kullanmadan, şimdi kullanılarak yapılabilir $sce. Denetleyiciye enjekte edin ve html'yi içinden geçirin. $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);Aksi takdirde almaya devam ettimattempting to use an unsafe value in a safe context
Matsemann

3
Burada biraz temizliğe ihtiyacımız var ki bu benim için hiçbir şeyin işe yaramadığı doğru yoldur.
indi

9
stackoverflow.com/questions/21829275/… <- benim için çalıştı :) buradaki cevaplardaki seçeneklerin hiçbiri maalesef işe yaramadı
anpatel

7
İnsanların cesaretini kırmamak için, cevabın altındaki ngSanitize gereksinimi ile birlikte bu cevabın en son güncellemesi aslında işe yarıyor.
Ben Cull

312

Bunun gibi bir filtre de oluşturabilirsiniz:

var app = angular.module("demoApp", ['ngResource']);

app.filter("trust", ['$sce', function($sce) {
  return function(htmlCode){
    return $sce.trustAsHtml(htmlCode);
  }
}]);

Sonra görünümde

<div ng-bind-html="trusted_html_variable | trust"></div>

Not : Bu filtre, kendisine geçirilen tüm html'lere güvenir ve kullanıcı girdisine sahip değişkenler geçirilirse bir XSS güvenlik açığı sunabilir.


@Katie Astrauskas, anwer için teşekkürler! Çok temiz bir yol. BTW ngResourcebağımlılığı gerekli değildir.
Athlan

28
Bunu yalnızca HTML'ye tamamen güvendiğinizde kullanın. Bu, HTML'yi hiçbir şekilde sterilize etmez, ancak yalnızca Angular'ın sayfaya enjekte etmesine izin verir. Kötü amaçlı HTML, XSS saldırılarına neden olabilir.
jan.vdbergh

Performans önemliyse, filtreler kullanmaktan kaçınmalısınız. Bir filtre her seferinde iki sindirimi tetikler.
Tantelope

14
Filtre neden çağırılır sanitize? Bu aslında hiçbir şeyi sterilize etmediği için yanıltıcıdır. Bunun yerine çağrılmalıdır trust, trustSafeya da buna benzer bir şey.
Denis Pshenov

1
Harika cevap. rawHtmlfiltre yerine benim adım sanitize.
Wumms

119

Açısal JS, etiketin içindeki HTML kodunu gösterir

Yukarıdaki bağlantıda sağlanan çözüm benim için çalıştı, bu konudaki seçeneklerin hiçbiri işe yaramadı. AngularJS sürüm 1.2.9 ile aynı şeyi arayan herkes için

İşte bir kopyası:

Tamam bunun için bir çözüm buldum:

JS:

$scope.renderHtml = function(html_code)
{
    return $sce.trustAsHtml(html_code);
};

HTML:

<p ng-bind-html="renderHtml(value.button)"></p>

DÜZENLE:

İşte kurulum:

JS dosyası:

angular.module('MyModule').controller('MyController', ['$scope', '$http', '$sce',
    function ($scope, $http, $sce) {
        $scope.renderHtml = function (htmlCode) {
            return $sce.trustAsHtml(htmlCode);
        };

        $scope.body = '<div style="width:200px; height:200px; border:1px solid blue;"></div>'; 

    }]);

HTML dosyası:

<div ng-controller="MyController">
    <div ng-bind-html="renderHtml(body)"></div>
</div>

7
Html'ye güvenilebileceğinden kesinlikle emin olmanız gerektiğini unutmayın. Aksi takdirde, kapı XSS ​​saldırılarına tamamen açıktır.
jan.vdbergh

HTML'yi oluşturmak için bir işlev kullanan bu çözüm, benim için çalışan tek çözümdür.
MarceloBarbosa

'$ http' ne için?
Soldeplata Saketos

@SoldeplataSaketos özellikle hiçbir şey, sanırım o zaman yerel olarak deniyordum ve bağımlılığı kopyaladım.
anpatel

Aynı cevap güncellemesi burada. stackoverflow.com/questions/21829275/…
Surya R Praveen

65

Neyse ki, bu hata mesajını önlemek için fantezi filtrelere veya güvenli olmayan yöntemlere ihtiyacınız yoktur. Bu, bir görünümde HTML biçimlendirmesini istenen ve güvenli bir şekilde düzgün şekilde çıktılamak için eksiksiz bir uygulamadır.

Dezenfektan modülü Açısal'dan sonra dahil edilmelidir:

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-sanitize.js"></script>

Ardından, modül yüklenmelidir:

angular.module('app', [
  'ngSanitize'
]);

Bu, bir denetleyiciden, yönergeden vb. Bir dizeye biçimlendirme eklemenizi sağlar:

scope.message = "<strong>42</strong> is the <em>answer</em>.";

Son olarak, bir şablonda şöyle çıktı alınmalıdır:

<p ng-bind-html="message"></p>

Hangi beklenen çıktıyı üretecek: 42 olduğu cevabı .


1
Gibi bazı html deneyin <div><label>Why My Input Element Missing</label><input /></div>... Eğer u sürprizleri sonra cevap plz güncelleyin .. Çünkü tüm 10 + oy çözümleri test .. Çözüm benim giriş etiketleri görmek için benim için işe yaramadı .. aksi takdirde iyi .. ben kullanmıştı$sce.trustAsHtml(html)
Sami

Bu çözüm işe yarıyor, bir jsfiddle veya plunkr yayınlamak ister misiniz?
Pier-Luc Gendreau

En son açısal kullanılıyorsa bu gerçekten cevap olmalı
Sandeep

61

Bugün denedim, bulmanın tek yolu şuydu

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


6
Bu çözüm, yalnızca siteler arası komut dosyası çalıştırma saldırılarını önlemek için kaynak güvenilirse kullanılmalıdır.
Bertrand

3
Açısal 1.0.2'den itibaren, bu benim için çalışır, başka dosya veya bağlantı gerekmez.
enigment

1
Açısal 1.0.8 kullanmak ve bu benim için çalıştı. Bertrand'ın uyarısını dikkate alın, kaynağa güvendiğinizden emin olun.
Jack Slingerland

12
Gelecekte referans olması için sürüm 1.2'de ng-bind-html-güvensiz kaldırılmıştır. Şimdi ngSanitize modülüne ihtiyacınız var ve güvensiz html'yi bağlamak için $ sce.trustAsHtml yöntemini kullanmalısınız.
Lucas Lazaro

53

ng-bind-html-unsafe Artık çalışmıyor.

Bu en kısa yol:

Bir filtre oluşturun:

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

Ve sizce:

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

PS Bu yöntem, ngSanitizemodülü dahil etmenizi gerektirmez .


3
Bu, Açısal 1.2 için burada gördüğüm en iyi çözüm. $sceKabul edilen cevapta kullanılan çözüm benim için işe yaramadı ve bu kadar önemsiz bir şey için ek bir bağımlılık eklemek istemedim.
Daniel Bonnell

Bidhan Bhattarai'nin çözümü benim için çalıştı. Açısal 1.6.1
mediaguru

25

html'de

<div ng-controller="myAppController as myCtrl">

<div ng-bind-html-unsafe="myCtrl.comment.msg"></div>

VEYA

<div ng-bind-html="myCtrl.comment.msg"></div

kontrolörde

mySceApp.controller("myAppController", function myAppController( $sce) {

this.myCtrl.comment.msg = $sce.trustAsHtml(html);

ile de çalışır $scope.comment.msg = $sce.trustAsHtml(html);


1
$scetemiz, ancak bir kullanıcı buraya bir kesme noktası ekleyemez ve this.myCtrl.comment.msgbir hata ayıklayıcı kullanarak herhangi bir kötü amaçlı kodu geri yükleyemez mi?
BradGreens

sonra tekrar BradGreens, ng-bind-html-güvensiz ile de aynı şeyi yapabilir misiniz?
CodeOverRide

4
Birisi orada kendi tarayıcı kesmek isterse, kimin umurunda. Diğer kullanıcıları etkilemez. @BradGreens Soru bu mu?
Chris Stephens

@ChrisStephens haklısın. Sanırım bu sorumu cevaplıyor ama benim görüşüme göre bu özellikler algılanan güvenliğe gerçek güvenlikten daha yakın. Belki de bir tür otomatik saldırılara karşı korur? Bu şeyleri yapmanın neden uygulamaya gerçekten yardımcı olduğunu asla anlamadım. Uygulamamın satır içi CSS'si olabileceğinden, wysiwyg HTML oluşturma HER örneğine bir filtre eklemek zorundadır ng-bind-html.
BradGreens

1
Bu özellikler güvenli kodlama hatalarını azaltmaya yardımcı olur. Özellikle biçimlendirme / kod enjeksiyonu ile ilgili sorun. Varsayılan olarak tüm bağlı veriler görüntüleme için kodlanmıştır. Temel olarak işaretleme çıktısı almak istiyorsanız, bu sizi ne yapmaya çalıştığınızı düşünmeye zorlar. Bu özellikler olmadan, yalnızca sunucu tarafı güvenliği ile çok şey yapabilirsiniz, ancak endişeleri ayırmak için istemci uygulaması verileri görüntülemek için doğru şekilde işlemekten sorumlu olmalıdır.
Chris Stephens

9

Ng-sanitize kullanmanın html'ye ng-click eklememe izin vermediğini buldum.

Bunu çözmek için bir direktif ekledim. Bunun gibi:

app.directive('htmldiv', function($compile, $parse) {
return {
  restrict: 'E',
  link: function(scope, element, attr) {
    scope.$watch(attr.content, function() {
      element.html($parse(attr.content)(scope));
      $compile(element.contents())(scope);
    }, true);
  }
}
});

Ve bu HTML:

<htmldiv content="theContent"></htmldiv>

İyi şanslar.


6

Bunu açısal (v1.4) dokümanları izleyerek ngBindHtml kullanarak yaptık ,

<div ng-bind-html="expression"></div> 
and expression can be "<ul><li>render me please</li></ul>"

Modül bağımlılıklarına ngSanitize eklediğinizden emin olun. O zaman iyi çalışmalı.


4

Kapsamlı bir öznitelik kullanmak dışında blrbr'lere çok benzeyen başka bir çözüm:

angular.module('app')
.directive('renderHtml', ['$compile', function ($compile) {
    return {
      restrict: 'E',
      scope: {
        html: '='
      },
      link: function postLink(scope, element, attrs) {

          function appendHtml() {
              if(scope.html) {
                  var newElement = angular.element(scope.html);
                  $compile(newElement)(scope);
                  element.append(newElement);
              }
          }

          scope.$watch(function() { return scope.html }, appendHtml);
      }
    };
  }]);

Ve sonra

<render-html html="htmlAsString"></render-html>

Not element.append()ile değiştirebilirsinizelement.replaceWith()


3

açısal olarak yeni öznitelik veya yönergeler oluşturmayı kullanarak bu soruna bir çözüm daha var .

Ürün-specs.html

 <h4>Specs</h4>
        <ul class="list-unstyled">
          <li>
            <strong>Shine</strong>
            : {{product.shine}}</li>
          <li>
            <strong>Faces</strong>
            : {{product.faces}}</li>
          <li>
            <strong>Rarity</strong>
            : {{product.rarity}}</li>
          <li>
            <strong>Color</strong>
            : {{product.color}}</li>
        </ul>

app.js

 (function() {
var app = angular.module('gemStore', []);    
app.directive("     <div ng-show="tab.isSet(2)" product-specs>", function() {
return {
  restrict: 'E',
  templateUrl: "product-specs.html"
};
});

index.html

 <div>
 <product-specs>  </product-specs>//it will load product-specs.html file here.
 </div>

veya

<div  product-specs>//it will add product-specs.html file 

veya

<div ng-include="product-description.html"></div>

https://docs.angularjs.org/guide/directive


3

ng-include komutunu da kullanabilirsiniz .

<div class="col-sm-9 TabContent_container" ng-include="template/custom.html">
</div>

bu şablon verilerini gizlemek için "ng-show" kullanabilirsiniz.


Ng-include'i kullanmak için tek yapmanız gereken bu mu?
Kasım'da fauverizm

evet .. denedim. ve eğer şablonu kullanıyorsanız, bunu aşağıdaki şekilde kullanın - <script type = "text / ng-template" id = "custom.html">
Vikash Sharma

2

İşte çözüm böyle bir filtre yapmak

.filter('trusted',
   function($sce) {
     return function(ss) {
       return $sce.trustAsHtml(ss)
     };
   }
)

ve bunu ng-bind-html dosyasına bir filtre olarak uygulayın.

<div ng-bind-html="code | trusted">

ve Ruben Decrop'a teşekkürler


1

kullanım

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

ve

angular.module('MyApp', ['ngSanitize']);

Bunun için, angular-sanitize.jsörneğin html dosyasına

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-sanitize.js"></script>

0

İşte basit (ve güvenli olmayan) bir bind-as-htmldirektif, aşağıdakilere ihtiyaç duymadan ngSanitize:

myModule.directive('bindAsHtml', function () {
    return {
        link: function (scope, element, attributes) {
            element.html(scope.$eval(attributes.bindAsHtml));
        }
    };
});

Güvenilmeyen içerik bağlanırsa bunun güvenlik sorunlarına yol açacağını unutmayın.

Şöyle kullanın:

<div bind-as-html="someHtmlInScope"></div>

-1

Açısal 4 ile şablonda html görüntülemek için boru ile çalışma örneği.

1.Kablolu Boru Kaçış-html.pipe.ts

'

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({name : 'keepHtml', pure : false})
export class EscapeHtmlPipe implements PipeTransform{
 constructor(private sanitizer : DomSanitizer){
 }
 transform(content){
  return this.sanitizer.bypassSecurityTrustHtml(content);
 }
}

`2. Boruyu app.module.ts dosyasına kaydedin

 import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
    declarations: [...,EscapeHtmlPipe]
  1. Şablonunuzda kullanın

        <div class="demoPipe"  [innerHtml]="getDivHtml(obj.header) | keepHtml">

  2. getDivHtml() { //can return html as per requirement}

    Lütfen related component.ts dosyasına getDivHtml için uygun uygulamaları ekleyin.


1
Bence yeni sürümü değil, AngularJS ile çalışıyor.
Leprosy

-1

[innerHTML]Aşağıdaki gibi sadece basit kullanım :

<div [innerHTML]="htmlString"></div>

Kullanmanız gerekmeden önce ng-bind-html...


Bu, AngularJS (Angular sürüm 1) için değil, yalnızca Angular (Angular sürüm 2+) içinde kullanılabilir.
ste2425

-1

Açısal 7 + iyonik 4'te, Html içerikleri "[innerHTML]" kullanılarak gösterilebilir:

<div [innerHTML]="htmlContent"></div>

Umarım bu da size yardımcı olacaktır. Teşekkürler.


lütfen bana bu yazıda neyin yanlış olduğunu neden olan bu kodda ne olduğunu söyle. Bu kodu benim 2 uygulamada test ettim. İşe yarıyor. Lütfen deneyiminizi paylaşın. Çok teşekkürler.
Kamlesh

1
Açısal JS, Açısal 1.x'e eşittir. Açısal 7 tamamen farklı bir çerçevedir
Aw Snap
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.