앵귤러 템플릿에서 innerHTML과 DomSanitizer를 사용하는 방법

5 분 소요

블로그 앱에서 tinymce 같은 플러그인을 사용해서 데이터를 저장하면 HTML 코드가 데이터베이스에 저장이 됩니다. 이런 데이터를 다시 앵귤러 템플릿에서 표시를 하기위한 방법을 알아보도록 하겠습니다.

데이터 베이스에 저장된 HTML 코드가 아래와 같다고 가정하겠습니다.

<h1><span style="color: #f1c40f;">안녕하세요. 이상희입니다.</span></h1>

일반적으로 가장 많이 실수를 하는 것이 아래와 같이 HTML 코드를 태그 안에 그대로 삽입하는 것인데요...

<div class="post-content">{{ post.content }}</div>

위와 같이 하시면 아래 이미지와 같이 HTML 코드가 일반 택스트로 그대로 출력이 되는 문제가 발생합니다.

HTML 코드가 그대로 출력되는 문제
HTML 코드가 그대로 출력되는 문제

이 문제를 해결하기 위해서는 아래와 같이 innerHTML 속성 바인딩 (property biding)을 사용하시면 됩니다.

<div class="post-content" [innerHTML]="post.content"></div>
인라인 스타일이 사라지는 문제 발생
인라인 스타일이 사라지는 문제 발생

HTML 코드가 잘 반영이 되어 표시는 되었습니다만, 다른 문제가 발생했습니다. 개발자 툴을 사용해서 실제 적용된 코드를 보면 아래와 같이 span 태그에 포함되어 있던 인라인 CSS 스타일이 사라진 것을 확인할 수 있습니다... 😥

개발자 툴에서 코드 확인
개발자 툴에서 코드 확인

이 문제가 발생하는 이유는 앵귤러 시스템이 위험한 코드가 HTML 코드에 포함되는 것을 방지하기 위한 기능입니다. 이 문제는 앵귤러가 제공하는 DomSanitizer 클래스를 사용해서 간단히 해결할 수 있습니다.

먼저 템플릿에서 사용 가능한 파이프 클래스를 생성하겠습니다.

$ ng g pipe trust-html

trust-html.pipe.ts 가 생성이 되면 아래 코드와 같이 수정을 합니다.

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

app.module.tsdeclarations에 포함시켜주는 것도 잊지마시고요.

import { TrustHtmlPipe } from './pipes/trust-html.pipe';
 
@NgModule({
  declarations: [
    AppComponent,
    ... 생략 ...
    TrustHtmlPipe,
  ],

그럼 생성한 파이프를 템플릿에서 사용하도록 하겠습니다.

<div class="post-content" [innerHTML]="post.content | trustHtml"></div>
정상적으로 출력되는 경우
정상적으로 출력되는 경우

어떤가요? 그렇게 어렵지 않죠? 😉 이번 강좌에서는 innerHTML 속성 바인딩과 파이프(pipe) 클래스에 대해서 공부했습니다. 해피 코딩하세요~~~!