Masukkan HTML ke tampilan dari pengontrol AngularJS

800

Apakah mungkin untuk membuat fragmen HTML di pengontrol AngularJS dan menampilkan HTML ini dalam tampilan?

Ini berasal dari persyaratan untuk mengubah gumpalan JSON yang tidak konsisten menjadi daftar id: valuepasangan bersarang . Karena itu HTML dibuat di controller dan sekarang saya ingin menampilkannya.

Saya telah membuat properti model, tetapi tidak dapat membuat ini dalam tampilan tanpa hanya mencetak HTML .


Memperbarui

Tampaknya masalah muncul dari rendering sudut HTML yang dibuat sebagai string dalam tanda kutip. Akan berusaha mencari jalan keluar.

Pengontrol contoh:

var SomeController = function () {

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

Contoh tampilan:

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

Memberi:

<div>
    "<ul><li>render me please</li></ul>"
</div>
Swaff
sumber
1
Silakan juga lihat pertanyaan ini , menanyakan apakah mungkin untuk membuat skrip dalam HTML yang dimasukkan untuk dijalankan.
enigment
Apakah mungkin untuk memiliki beberapa objek yang terikat pada ng-bind yang sama? seperti `` `ng-bind =" site.address_1 site.address_2 site.zip "
fauverism
jika Anda memiliki banyak hal pada halaman Anda, Anda harus mengubah baris 15046 dari angular.js (insanity) of function htmlSanitizer(html) {.... Sudut dev memutuskan bahwa Anda harus dapat menemukan html mengikat dengan perlahan-lahan melalui semua halaman Anda elemen tersembunyi satu per satu untuk menemukan bahwa SATU TUNGGU kehilangan sepotong html. !!! sangat marah dengan asumsi seperti itu !!!
user3338098
Maaf, jawaban yang dipilih oleh Luke mungkin bukan jawaban yang sepenuhnya benar. Jawaban yang tepat dapat ditemukan di pertanyaan lain di sini . Pada dasarnya, "ng-bind-html-tidak aman hanya menjadikan konten sebagai HTML. Itu tidak mengikat lingkup Angular ke DOM yang dihasilkan. Anda harus menggunakan layanan $ compile untuk tujuan itu."
gm2008
ng-bind menghapus semua html internal. yang bukan bagaimana filter akan bekerja, tidak apa-apa ketika filter adalah satu-satunya nilai
Muhammad Umer

Jawaban:

1120

Untuk Angular 1.x, gunakan ng-bind-htmldalam HTML:

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

Pada titik ini Anda akan mendapatkan attempting to use an unsafe value in a safe contextkesalahan sehingga Anda perlu menggunakan ngSanitize atau $ sce untuk menyelesaikannya.

$ sce

Gunakan $sce.trustAsHtml()di pengontrol untuk mengonversi string html.

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

ng Sanitasi

Ada 2 langkah:

  1. termasuk sumber daya angular-sanitize.min.js, yaitu:
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. Dalam file js (controller atau biasanya app.js), sertakan ngSanitize, yaitu:
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])

Luke Madera
sumber
30
Dalam Angular 1.2, ng-bind-html-unsafetelah dihapus dan dua arahan digabungkan. Lihat: github.com/angular/angular.js/blob/master/…
Sasha Chedygov
60
Tanpa menggunakan ngSanitize, sekarang dapat dilakukan dengan menggunakan $sce. Suntikkan ke pengontrol dan berikan html melaluinya. $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);Kalau tidak, saya terus mendapatkanattempting to use an unsafe value in a safe context
Matsemann
3
Kami perlu sedikit pembersihan di sini yang merupakan cara yang benar sepertinya tidak ada yang bekerja untuk saya.
mendarat
9
stackoverflow.com/questions/21829275/… <- bekerja untuk saya :) tidak ada opsi dalam jawaban di sini yang bekerja sayangnya
anpatel
7
Supaya orang tidak berkecil hati, pembaruan terbaru dari jawaban ini, ditambah dengan persyaratan ngSanitize di bagian bawah jawaban, ternyata bekerja.
Ben Cull
312

Anda juga dapat membuat filter seperti:

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

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

Lalu dalam tampilan

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

Catatan : Filter ini mempercayai setiap dan semua html yang diteruskan ke sana, dan bisa menyajikan kerentanan XSS jika variabel dengan input pengguna diteruskan ke sana.

Katie Astrauskas
sumber
@Katie Astrauskas, terima kasih atas jawabannya! Cara yang sangat bersih. ngResourceKetergantungan BTW tidak perlu.
Athlan
28
Gunakan ini hanya saat Anda benar-benar mempercayai HTML. Ini tidak membersihkan HTML dengan cara apa pun, tetapi hanya memungkinkan Angular untuk menyuntikkannya ke halaman. HTML berbahaya dapat memicu serangan XSS.
jan.vdbergh
Jika kinerjanya penting, Anda harus menghindari penggunaan filter. Sebuah filter akan memicu dua intisari setiap kali.
Tantelope
14
Mengapa filter disebut sanitize? Ini sangat menyesatkan karena sebenarnya tidak membersihkan apa pun. Sebaliknya harus disebut trust, trustSafeatau yang serupa.
Denis Pshenov
1
Jawaban yang bagus rawHtmladalah nama saya untuk filter, bukan sanitize.
Wumms
119

Angular JS menunjukkan HTML di dalam tag

Solusi yang disediakan di tautan di atas bekerja untuk saya, tidak ada opsi di utas ini yang berfungsi. Bagi siapa pun yang mencari hal yang sama dengan AngularJS versi 1.2.9

Ini salinannya:

Ok saya menemukan solusi untuk ini:

JS:

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

HTML:

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

EDIT:

Inilah pengaturannya:

File JS:

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>'; 

    }]);

File HTML:

<div ng-controller="MyController">
    <div ng-bind-html="renderHtml(body)"></div>
</div>
anpatel
sumber
7
Ketahuilah bahwa Anda harus benar-benar yakin bahwa html dapat dipercaya. Kalau tidak, pintu terbuka lebar untuk serangan XSS.
jan.vdbergh
Solusi ini, menggunakan fungsi untuk membuat HTML, adalah satu-satunya yang bekerja untuk saya.
MarceloBarbosa
untuk apa '$ http'?
Soldeplata Saketos
@SoldeplataSaketos tidak ada yang khusus, saya pikir saya sedang mencobanya secara lokal pada saat itu dan akhirnya saya menyalin ketergantungan.
anpatel
Pembaruan jawaban yang sama di sini. stackoverflow.com/questions/21829275/…
Surya R Praveen
65

Untungnya, Anda tidak memerlukan filter mewah atau metode tidak aman untuk menghindari pesan kesalahan itu. Ini adalah implementasi lengkap untuk menampilkan markup HTML dengan benar dalam tampilan dengan cara yang dimaksudkan dan aman.

Modul sanitasi harus dimasukkan setelah Angular:

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

Kemudian, modul harus dimuat:

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

Ini akan memungkinkan Anda untuk memasukkan markup dalam string dari pengontrol, direktif, dll:

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

Akhirnya, dalam templat, harus berupa output seperti:

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

Yang akan menghasilkan output yang diharapkan: 42 adalah jawabannya .

Dermaga-Luc Gendreau
sumber
1
Coba beberapa html seperti <div><label>Why My Input Element Missing</label><input /></div>... Jika Anda terkejut maka perbarui jawaban Anda .. Karena saya menguji semua 10 + solusi suara .. Solusi Anda tidak berhasil bagi saya untuk melihat tag input saya .. baik jika tidak .. saya telah menggunakan$sce.trustAsHtml(html)
Sami
Solusi ini berhasil, apakah Anda mau memposting jsfiddle atau plunkr?
Pier-Luc Gendreau
Ini benar-benar harus menjadi jawaban jika menggunakan sudut terbaru
Sandeep
61

Saya sudah mencoba hari ini, satu-satunya cara saya temukan adalah ini

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

Damax
sumber
6
Solusi ini harus digunakan hanya jika sumbernya dipercaya untuk menghindari serangan skrip lintas situs.
Bertrand
3
Pada Angular 1.0.2, ini berfungsi untuk saya, tanpa perlu file atau sambungan lainnya.
enigment
1
Menggunakan Angular 1.0.8 dan ini berhasil untuk saya. Peringatan Heed @ Bertrand, pastikan Anda memercayai sumbernya.
Jack Slingerland
12
Untuk referensi di masa mendatang, ng-bind-html-unsafe dihapus dalam versi 1.2. Sekarang Anda memerlukan modul ngSanitize dan untuk mengikat html yang tidak aman, Anda harus menggunakan metode $ sce.trustAsHtml.
Lucas Lazaro
53

ng-bind-html-unsafe tidak lagi berfungsi.

Ini cara terpendek:

Buat filter:

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

Dan menurut Anda:

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

PS Metode ini tidak mengharuskan Anda untuk memasukkan ngSanitizemodul.

Bidhan Bhattarai
sumber
3
Ini adalah solusi terbaik yang pernah saya lihat di sini untuk Angular 1.2. Solusi yang digunakan $scedalam jawaban yang diterima tidak bekerja untuk saya dan saya tidak ingin menyertakan ketergantungan tambahan untuk sesuatu yang begitu sepele.
Daniel Bonnell
Solusi oleh Bidhan Bhattarai bekerja untuk saya. Sudut 1.6.1
mediaguru
25

di html

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

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

ATAU

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

pada pengontrol

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

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

bekerja juga dengan $scope.comment.msg = $sce.trustAsHtml(html);

Sotos
sumber
1
$scerapi tetapi tidak bisakah pengguna menambahkan breakpoint di sini dan mengembalikan kode berbahaya apa pun ke this.myCtrl.comment.msgmenggunakan debugger?
BradGreens
sekali lagi BradGreens, apakah Anda dapat melakukan hal yang sama dengan ng-bind-html-tidak aman juga?
CodeOverRide
4
Jika seseorang ingin meretas di sana, peramban mereka dapat, siapa yang peduli. Itu tidak akan mempengaruhi pengguna lain. @BradGreens Apakah itu pertanyaannya?
Chris Stephens
@ ChrisStephens Anda benar. Saya kira itu memang menjawab pertanyaan saya tetapi pendapat saya adalah fitur-fitur ini lebih dekat dengan keamanan yang dirasakan daripada keamanan sebenarnya. Mungkin itu melindungi terhadap beberapa jenis serangan otomatis? Saya tidak pernah mengerti mengapa melakukan hal ini sangat membantu aplikasi. Aplikasi saya harus menambahkan filter ke SETIAP contoh rendering wysiwyg HTML karena bisa memiliki inline CSS, yang ng-bind-htmlmenghapus.
BradGreens
1
Nah fitur ini membantu mengurangi kesalahan pengkodean yang aman. Khususnya masalah dengan markup / injeksi kode. Secara default semua data terikat dikodekan untuk ditampilkan. Jadi pada dasarnya jika Anda ingin menampilkan markup ini memaksa Anda untuk berpikir tentang apa yang Anda coba lakukan. Tanpa fitur-fitur ini Anda dapat melakukan banyak hal dengan keamanan sisi server saja tetapi untuk masalah yang terpisah aplikasi klien harus bertanggung jawab menangani data dengan benar untuk tampilan.
Chris Stephens
9

Saya menemukan bahwa menggunakan ng-sanitize tidak memungkinkan saya untuk menambahkan ng-klik di html.

Untuk mengatasi ini saya menambahkan arahan. Seperti ini:

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

Dan ini adalah HTML:

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

Semoga berhasil.

Mat
sumber
6

Baru saja melakukan ini menggunakan ngBindHtml dengan mengikuti sudut (v1.4) dokumen ,

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

Pastikan Anda memasukkan ngSanitize dalam dependensi modul. Maka itu harus bekerja dengan baik.

Henry Neo
sumber
4

Solusi lain, sangat mirip dengan blrbr kecuali menggunakan atribut scoped adalah:

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

Lalu

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

Catatan Anda dapat mengganti element.append()denganelement.replaceWith()

abbaf33f
sumber
3

ada satu solusi lagi untuk masalah ini menggunakan menciptakan atribut atau arahan baru dalam sudut.

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

atau

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

atau

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

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

yugi
sumber
3

Anda juga dapat menggunakan ng-include .

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

Anda dapat menggunakan "ng-show" untuk memperlihatkan sembunyikan data templat ini.

Vikash Sharma
sumber
Anda yakin ini semua yang perlu Anda lakukan agar dapat menggunakan ng-include?
fauverisme
ya .. saya sudah mencobanya. dan jika Anda menggunakan template maka gunakan dengan cara berikut - <script type = "text / ng-template" id = "custom.html">
Vikash Sharma
2

ini solusinya buat filter seperti ini

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

dan terapkan ini sebagai filter ke ng-bind-html like

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

dan terima kasih kepada Ruben Decrop

bahri noredine
sumber
1

Menggunakan

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

dan

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

Untuk itu, Anda perlu memasukkan angular-sanitize.js, misalnya dalam file html Anda dengan

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

Berikut adalah bind-as-htmlarahan sederhana (dan tidak aman) , tanpa perlu ngSanitize:

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

Perhatikan bahwa ini akan terbuka untuk masalah keamanan, jika mengikat konten yang tidak dipercaya.

Gunakan seperti ini:

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

sumber
-1

Contoh kerja dengan pipa untuk menampilkan html di templat dengan Angular 4.

1.Crated Pipe escape-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. Daftarkan pipa ke app.module.ts

 import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
    declarations: [...,EscapeHtmlPipe]
  1. Gunakan di template Anda

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

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

    Silakan tambahkan implementasi yang sesuai untuk getDivHtml di file component.ts terkait.

Sagar Misal
sumber
1
Saya pikir dia bekerja dengan AngularJS, bukan versi yang lebih baru.
Kusta
-1

Cukup gunakan sederhana [innerHTML], seperti di bawah ini:

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

Sebelum Anda perlu menggunakan ng-bind-html...

Alireza
sumber
Ini hanya tersedia dalam Angular (Angular versi 2+), bukan AngularJS (Angular versi 1).
ste2425
-1

Dalam Angular 7 + ionic 4, konten Html dapat ditampilkan dengan menggunakan "[innerHTML]":

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

Saya harap, ini juga akan membantu Anda. Terima kasih.

Kamlesh
sumber
tolong beri tahu saya apa yang salah dalam kode ini yang menyebabkan downvote posting ini. Saya telah menguji kode ini di 2 aplikasi saya. Berhasil. Silakan bagikan pengalaman Anda. Terima kasih banyak.
Kamlesh
1
AngularJS sama dengan Angular 1.x. Sudut 7 adalah kerangka kerja yang sama sekali berbeda
Aw Snap