Svelte

[Svelte]문자열을 HTML로 표현

DevStory 2022. 8. 5.

문자열을 html로 표현

Svelte 컴포넌트에서 문자열 형태의 html을 HTML 영역에 표시하면, 문자열이 출력됩니다.

<script>
  let markup = '<h1>Hi!</h1>';
</script>

<div>
  {markup}
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]


Svelte에서 문자열 형태의 html을 html로 표현하고 싶다면, 컴포넌트의 HTML 영역에서 @html 문법을 사용합니다.

<script>
  let markup = '<h1>Hi!</h1>';
</script>

<div>
  {@html markup}
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]


다음 소스 코드는 textarea에서 입력받은 문자열을 html로 표현합니다.

<script>
  let strValue = '';
</script>

<div>
  <textarea bind:value={strValue} />
  <p>
  {@html strValue}
  </p>
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]


크로스 사이트 스크립트

공격자가 웹 애플리케이션의 취약점을 이용하여 악성 html, javascript 코드를 삽입하여 비정상적인 기능을 수행하도록 하는 공격 기법입니다.

 

textarea에 악성 html 코드를 삽입하여 웹 애플리케이션이 비정상적으로 동작할 수 있는데, @html은 script 요소를 삽입하면 해당 코드는 실행되지 않습니다.

 

실행되지는 않더라도 악성 코드는 남아있기에 충분히 문제가 될 만한 요인입니다. 문자열 형태의 html을 html로 표현하는 과정에서 위험한 문자열을 제거하는 라이브러리를 사용하면 크로스 사이트 스크립트를 피할 수 있습니다.


sanitize-html 라이브러리

오픈소스 라이브러리인 santitize-html는 문자열 형태의 html에서 위험한 html 문자열을 제거합니다. sanitize-html 라이브러리를 사용하기 위해 다음 명령어로 라이브러리를 설치합니다.

 

[npm 명령어]

npm install sanitize-html

[yarn 명령어]

yarn add sanitize-html

@rollup/plugin-json 에러 발생

sanitize-html 라이브러리를 설치하면 @rollup/plugin-json 라이브러리가 필요하다고 에러가 발생할 수 있습니다.

해당 라이브러리를 다음 명령어로 설치합니다.

 

[npm 명령어]

npm i @rollup/plugin-json --save-dev

[yarn 명령어]

yarn add @rollup/plugin-json

 

package.json 파일에서 @rollup/plugin-json 라이브러리가 정상적으로 설치되었는지 확인합시다.

다음으로 rollup.config.js 파일을 확인합니다. @rollup/plugin-json을 import 하는 코드가 없다면, 다음 사진처럼 @rollup/plugin-json 라이브러리를 import 합니다.

plugins에 json()을 추가합니다.

에러 해결 참고 사이트

 

Svelte (rollup) - Error: Unexpected token (Note that you need @rollup/plugin-json to import JSON files)

I am doing nothing to trigger this error. The app works fine one second, and doesn't the next. Why is this happening? It is not due to the missing @rollup/plugin-json plugin because it worked previ...

stackoverflow.com


sanitizeHtml 함수

sanitize-html 라이브러리의 sanitizeHtml() 함수는 세 개의 인자를 가집니다.

 

첫 번째 인자

- 문자열 형태의 html입니다.

 

두 번째 인자

- 특정 태그 또는 특정 속성만 허용되도록 설정하는 옵션입니다.

- 두 번째 인자를 생략하는 경우 기본 옵션으로 설정됩니다.

 

세 번째 인자

- true: 현재 속성과 새로운 속성을 병합합니다.

- false: 기존 속성이 모두 제거됩니다.

- 세 번째 인자를 생략하는 경우 true로 설정됩니다.


사용 방법 1. 기본

기본 옵션으로 h1 ~ h6 태그를 허용합니다.

<script>
  import sanitizeHtml from 'sanitize-html';
  let h1_tag = '<h1>h1_tag</h1>';
  let h2_tag = '<h2>h2_tag</h2>';
  let h3_tag = '<h3>h3_tag</h3>';
</script>

<div>
  {@html sanitizeHtml(h1_tag)}
  {@html sanitizeHtml(h2_tag)}
  {@html sanitizeHtml(h3_tag)}
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]


사용 방법 2. 옵션 설정

allowedTags 프로퍼티에 배열로 허용하고자 하는 HTML 태그를 작성합니다. 다음 예제는 h3 태그만 변환되도록 설정값을 sanitizeHtml() 함수에 전달합니다.

<script>
  import sanitizeHtml from 'sanitize-html';

  const SANITIZE_OPTION = {
    allowedTags: ['h3']
  };
  
  let h1_tag = '<h1>h1_tag</h1>';
  let h2_tag = '<h2>h2_tag</h2>';
  let h3_tag = '<h3>h3_tag</h3>';
</script>

<div>
  {@html sanitizeHtml(h1_tag, SANITIZE_OPTION)}
  {@html sanitizeHtml(h2_tag, SANITIZE_OPTION)}
  {@html sanitizeHtml(h3_tag, SANITIZE_OPTION)}
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]


사용 방법 3. 기존 옵션에서 추가

기존 옵션에서 변환 가능한 HTML 태그를 추가하고 싶은 경우 spread 연산자를 사용할 수 있습니다. 다음 예제는 기존 옵션을 유지하고 img 태그를 허용하도록 설정합니다.

<script>
  import sanitizeHtml from 'sanitize-html';

  const SANITIZE_OPTION = {
    allowedTags: [...sanitizeHtml.defaults.allowedTags, 'img']
  };
  
  let h1_tag = '<h1>h1_tag</h1>';
  let h2_tag = '<h2>h2_tag</h2>';
  let img_tag = '<img src="./favicon.png"' +
                'alt="favicon.png 없음">';
</script>

<div>
  {@html sanitizeHtml(h1_tag, SANITIZE_OPTION)}
  {@html sanitizeHtml(h2_tag, SANITIZE_OPTION)}
  {@html sanitizeHtml(img_tag, SANITIZE_OPTION)}
</div>

<style>
div {
  text-align: center;
}
</style>

[실행 결과]

다양한 옵션 활용 방법은 아래 공식 문서에서 확인할 수 있습니다.

 

sanitize-html

Clean up user-submitted HTML, preserving allowlisted elements and allowlisted attributes on a per-element basis. Latest version: 2.7.1, last published: 16 days ago. Start using sanitize-html in your project by running `npm i sanitize-html`. There are 1358

www.npmjs.com

반응형

댓글