AngularJS 컨트롤러에서 HTML을보기에 삽입


800

AngularJS 컨트롤러에서 HTML 단편 을 작성 하고이 HTML을보기에 표시 할 수 있습니까?

일치하지 않는 JSON Blob을 중첩 된 id: value쌍 목록으로 변환해야한다는 요구 사항에서 비롯됩니다 . 따라서 HTML 은 컨트롤러에서 만들어지며 이제 표시하려고합니다.

모델 속성을 만들었지 만 HTML을 인쇄하지 않으면 뷰에서 렌더링 할 수 없습니다 .


최신 정보

생성 된 HTML을 따옴표 안에 문자열로 앵귤러 렌더링하면 문제가 발생하는 것으로 보입니다. 이 문제를 해결할 방법을 찾으려고 노력할 것입니다.

컨트롤러 예 :

var SomeController = function () {

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

보기 예 :

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

제공합니다 :

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

1
또한 삽입 된 HTML로 스크립트를 실행할 수 있는지 묻는 이 질문을 참조하십시오 .
enigment December

동일한 ng-bind에 여러 객체를 바인딩 할 수 있습니까? ```ng-bind = "site.address_1 site.address_2 site.zip"
fauverism

페이지에 많은 내용이 있으면의 angular.js (insanity)의 15046 행을 변경해야합니다 function htmlSanitizer(html) {.... Angular dev는 하나의 누락 된 html 조각을 찾기 위해 모든 숨겨진 페이지 요소를 하나씩 차례로 탐색하여 html 바인딩을 찾을 수 있어야한다고 결정했습니다. !!! 그런 가정에 매우 화가 !!!
user3338098

죄송합니다. 누가가 선택한 답이 완전히 정답이 아닐 수도 있습니다. 정답은 다른 질문 에서 찾을 수 있습니다 . 기본적으로 "ng-bind-html-unsafe는 내용을 HTML로만 렌더링합니다. 결과 범위의 DOM에 Angular 범위를 바인딩하지 않습니다.이 목적으로 $ compile 서비스를 사용해야합니다."
gm2008

ng-bind는 모든 내부 HTML을 제거합니다. 필터가 작동하는 방식이 아니라 필터가 유일한 값일 때 괜찮습니다
Muhammad Umer

답변:


1120

Angular 1.x의 ng-bind-html경우 HTML에서 사용 하십시오.

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

이 시점에서 attempting to use an unsafe value in a safe context오류가 발생하므로 ngSanitize 또는 $ sce 를 사용 하여 문제를 해결해야합니다.

$ sce

$sce.trustAsHtml()컨트롤러에서 HTML 문자열을 변환하는 데 사용하십시오 .

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

ngSanitize

2 단계가 있습니다.

  1. angular-sanitize.min.js 리소스를 포함하십시오.
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. js 파일 (컨트롤러 또는 일반적으로 app.js)에 ngSanitize를 포함하십시오.
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])


30
Angular 1.2에서는 ng-bind-html-unsafe제거되었고 두 지시어가 결합되었습니다. 참조 : github.com/angular/angular.js/blob/master/…
Sasha Chedygov

60
ngSanitize를 사용하지 않고 지금을 사용하여 수행 할 수 있습니다 $sce. 컨트롤러에 넣고 HTML을 통과시킵니다. $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);그렇지 않으면 나는 계속 얻었습니다attempting to use an unsafe value in a safe context
Matsemann

3
우리는 여기에 약간의 정리가 필요합니다.
상륙

9
stackoverflow.com/questions/21829275/… <-나를 위해 일했습니다 :) 여기에 답변의 옵션 중 아무것도 불행히도 작동하지 않았습니다
anpatel

7
사람들이 낙심하지 않기 때문에이 답변의 최신 업데이트는 답변 맨 아래의 ngSanitize 요구 사항과 함께 실제로 작동합니다.
벤 컬

312

다음과 같이 필터를 만들 수도 있습니다.

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

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

그런 다음보기에서

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

참고 :이 필터는 전달 된 모든 HTML을 신뢰하며 사용자 입력이있는 변수가 전달되면 XSS 취약성을 나타낼 수 있습니다.


@Katie Astrauskas, anwer에 감사드립니다! 매우 깨끗한 방법입니다. BTW ngResource의존성은 필요하지 않습니다.
Athlan

28
HTML을 완전히 신뢰할 때만 사용하십시오. 이것은 HTML을 위생 처리하지 않지만 Angular가 HTML을 페이지에 삽입하도록 허용합니다. 악성 HTML이 XSS 공격을 유발할 수 있습니다.
jan.vdbergh

성능이 중요한 경우 필터 사용을 피해야합니다. 필터는 매번 2 개의 다이제스트를 트리거합니다.
Tantelope

14
왜 필터가 호출 sanitize됩니까? 실제로 아무것도 위생 처리하지 않기 때문에 오해의 소지가 있습니다. 대신 trust, trustSafe또는 이와 비슷한 이름으로 호출해야합니다 .
Denis Pshenov

1
훌륭한 답변입니다. rawHtml필터 대신 내 이름입니다 sanitize.
Wumms

119

Angular JS는 태그 내에 HTML을 보여줍니다

위의 링크에서 제공되는 솔루션은 저에게 효과적이었습니다.이 스레드의 옵션은 없습니다. AngularJS 버전 1.2.9와 동일한 것을 찾는 사람이라면

사본은 다음과 같습니다.

Ok 나는 이것에 대한 해결책을 찾았다.

JS :

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

HTML :

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

편집하다:

설정은 다음과 같습니다.

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

    }]);

HTML 파일 :

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

7
HTML을 신뢰할 수 있는지 반드시 확인해야합니다. 그렇지 않으면 XSS 공격에 대한 문이 넓게 열립니다.
jan.vdbergh

HTML을 렌더링하는 함수를 사용하는이 솔루션은 나에게 도움이 된 유일한 솔루션입니다.
MarceloBarbosa

'$ http'는 무엇입니까?
Soldeplata Saketos

@SoldeplataSaketos, 특히 아무것도 로컬에서 시도했지만 종속성을 복사하는 것으로 끝났습니다.
anpatel

동일한 답변 업데이트가 여기에 있습니다. stackoverflow.com/questions/21829275/…
Surya R Praveen

65

다행히도 오류 메시지를 피하기 위해 멋진 필터 나 안전하지 않은 방법이 필요하지 않습니다. 이것은 의도적이고 안전한 방식으로 HTML 마크 업을 올바르게 출력하기위한 완벽한 구현입니다.

살균 모듈은 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>

그런 다음 모듈을로드해야합니다.

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

이를 통해 컨트롤러, 지시문 등의 문자열에 마크 업을 포함시킬 수 있습니다.

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

마지막으로 템플릿에서 다음과 같이 출력되어야합니다.

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

예상 출력이 생성됩니다. 42 입니다.


1
<div><label>Why My Input Element Missing</label><input /></div>다음 과 같은 html을 시도해보십시오 ... 놀랍다면 대답 plz를 업데이트하십시오. 10 + 투표 솔루션을 모두 테스트했기 때문에 .. 귀하의 솔루션이 입력 태그를 볼 수 없었습니다.$sce.trustAsHtml(html)
Sami

이 솔루션은 효과가 있습니다. jsfiddle 또는 plunkr를 게시해야합니까?
Pier-Luc Gendreau

최신 각도를 사용한다면 이것이 정답
Sandeep

61

오늘 시도했지만 내가 찾은 유일한 방법은

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


6
이 솔루션은 사이트 간 스크립팅 공격을 피하기 위해 소스가 신뢰할 수있는 경우에만 사용해야합니다.
Bertrand

3
Angular 1.0.2부터는 다른 파일이나 연결이 필요하지 않으므로 저에게 효과적입니다.
enigment December

1
Angular 1.0.8을 사용하면 이것이 효과적입니다. @Bertrand의 경고에주의를 기울이십시오. 소스를 신뢰해야합니다.
잭 슬링거 랜드

12
나중에 참조 할 수 있도록 ng-bind-html-unsafe는 버전 1.2에서 제거되었습니다. 이제 ngSanitize 모듈이 필요하고 안전하지 않은 HTML을 바인딩하려면 $ sce.trustAsHtml 메소드를 사용해야합니다.
Lucas Lazaro

53

ng-bind-html-unsafe 더 이상 작동하지 않습니다.

가장 짧은 방법입니다.

필터를 작성하십시오.

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

그리고 당신의 관점에서 :

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

PS이 방법은 ngSanitize모듈 을 포함하지 않아도됩니다 .


3
이것이 제가 Angular 1.2에서 본 최고의 솔루션입니다. $sce허용 된 답변에 사용하는 솔루션 이 저에게 효과적이지 않았으므로 사소한 것에 대한 추가 종속성을 포함하고 싶지 않았습니다.
Daniel Bonnell

Bidhan Bhattarai의 솔루션이 저에게 효과적이었습니다. Angular 1.6.1
mediaguru

25

html로

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

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

또는

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

컨트롤러에서

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

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

함께 작동 $scope.comment.msg = $sce.trustAsHtml(html);


1
$sce깔끔하지만 사용자가 여기에 중단 점을 추가 this.myCtrl.comment.msg하고 디버거 를 사용하여 악성 코드를 복원 할 수 없었 습니까?
BradGreens

그런 다음 다시 BradGreens, ng-bind-html-unsafe로도 동일한 작업을 수행 할 수 있습니까?
CodeOverRide

4
누군가가 자신이 할 수있는 브라우저를 해킹하고 싶다면 신경 쓰십시오. 다른 사용자에게는 영향을 미치지 않습니다. @BradGreens 질문입니까?
Chris Stephens

@ChrisStephens 당신이 맞습니다. 나는 그것이 내 질문에 대답한다고 생각하지만 내 의견은 이러한 기능이 실제 보안보다 인식 된 보안에 더 가깝다는 것입니다. 아마도 어떤 종류의 자동 공격으로부터 보호 할 수 있습니까? 이 작업을 수행하는 것이 앱에 실제로 도움이되는 이유를 분명히 파악한 적이 없습니다. 내 응용 프로그램은 wysiwyg HTML을 렌더링하는 모든 인스턴스에 필터를 추가해야합니다. 인라인 CSS가있을 수 있기 때문 ng-bind-html입니다.
BradGreens

1
이러한 기능은 보안 코딩 실수를 줄이는 데 도움이됩니다. 특히 마크 업 / 코드 삽입과 관련된 문제입니다. 기본적으로 모든 바인딩 된 데이터는 표시되도록 인코딩됩니다. 따라서 기본적으로 마크 업을 출력하려면 수행하려는 작업에 대해 생각해야합니다. 이러한 기능이 없으면 서버 측 보안만으로도 많은 작업을 수행 할 수 있지만 클라이언트 앱은 데이터를 올바르게 처리하여 표시해야하는 문제를 구분해야합니다.
Chris Stephens

9

ng-sanitize를 사용하면 HTML에 ng-click을 추가 할 수 없었습니다.

이 문제를 해결하기 위해 지시문을 추가했습니다. 이처럼 :

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

그리고 이것은 HTML입니다.

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

행운을 빕니다.


6

angular (v1.4) docs 을 따라 ngBindHtml을 사용 하여이 작업을 수행했습니다 .

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

모듈의 종속성에 ngSanitize를 포함시켜야합니다. 그렇다면 잘 작동합니다.


4

범위가 지정된 속성을 사용한다는 점을 제외하고 blrbr과 매우 유사한 다른 솔루션은 다음과 같습니다.

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

그리고

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

당신이 대체 할 수 있습니다 element.append()element.replaceWith()


3

각도에서 새 속성 또는 지시문 을 작성하여이 문제점에 대한 하나 이상의 솔루션이 있습니다 .

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

또는

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

또는

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

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


3

ng-include 를 사용할 수도 있습니다 .

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

"ng-show" 를 사용 하여이 템플릿 데이터 숨기기를 표시 할 수 있습니다 .


ng-include를 사용하기 위해해야 ​​할 모든 것입니까?
fauverism

예 .. 나는 그것을 시도했다. 템플릿을 사용하는 경우 다음과 같이 사용하십시오-<script type = "text / ng-template"id = "custom.html">
Vikash Sharma

2

여기에 솔루션이 다음과 같은 필터를 만듭니다

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

이것을 ng-bind-html에 필터로 적용하십시오.

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

그리고 Ruben Decrop에게 감사합니다


1

사용하다

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

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

이를 위해서는 예 angular-sanitize.js를 들어 html 파일에을 포함해야합니다.

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

0

다음은 간단하고 안전하지 않은 bind-as-html지시어입니다 ngSanitize.

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

신뢰할 수없는 콘텐츠를 바인딩하는 경우 보안 문제가 발생합니다.

다음과 같이 사용하십시오.

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

-1

Angular 4를 사용하여 템플릿에 HTML을 표시하는 파이프 작업 예제

1. 정격 파이프 이스케이프 -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. app.module.ts에 파이프를 등록하십시오

 import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
    declarations: [...,EscapeHtmlPipe]
  1. 템플릿에서 사용

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

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

    연관된 component.ts 파일에 getDivHtml에 대한 적절한 구현을 추가하십시오.


1
나는 그가 최신 버전이 아닌 AngularJS와 함께 일하고 있다고 생각합니다.
Leprosy

-1

[innerHTML]아래와 같이 간단하게 사용하십시오 .

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

사용하기 전에 ng-bind-html...


AngularJS (Angular 버전 1)가 아닌 Angular (Angular 버전 2+)에서만 사용할 수 있습니다.
ste2425

-1

Angular 7 + ionic 4에서 "[innerHTML]"을 사용하여 HTML 내용을 표시 할 수 있습니다.

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

나는 이것이 또한 당신을 도울 것입니다 바랍니다. 감사.


친절 하게이 게시물에 투표를 유발하는이 코드의 문제점을 알려주십시오. 내 2 응용 프로그램 에서이 코드를 테스트했습니다. 효과가있다. 당신의 경험을 공유하십시오. 고마워
Kamlesh

1
AngularJS는 Angular 1.x와 같습니다. Angular 7은 완전히 다른 프레임 워크입니다.
Aw Snap
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.