Framework/React

[React] ๋ฆฌ์•กํŠธ innerHtml ํ‘œ์‹œํ•˜๊ธฐ (dangerouslySetInnerHTML)์‚ฌ์šฉ ์ฃผ์˜์  ๋ฐ ๋ณด์•ˆ ๋ฐฉ๋ฒ•

yuri lee 2023. 4. 6. 00:05
๋ฐ˜์‘ํ˜•

Intro 

์•ˆ๋…•ํ•˜์„ธ์š”. ๋ฆฌ์•กํŠธ์—์„œ innerHtml์„ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ตœ๊ทผ์— ์Šค๋งˆํŠธ์—๋””ํ„ฐ ๊ด€๋ จํ•œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์—๋””ํ„ฐ์— ์ €์žฅ๋œ ๋‚ด์šฉ์ด ๊ทธ๋Œ€๋กœ html tag๋กœ ์ €์žฅ๋˜๊ณ , ์ €์žฅ๋œ html tag๋ฅผ ๊ทธ๋Œ€๋กœ ํ™”๋ฉด์— ํ‘œ์‹œํ•ด์•ผ ํ–ˆ์ฃ . ์ €์žฅ๋œ ์ด innerHtml๋ฅผ ์–ด๋–ป๊ฒŒ ํ‘œ์‹œํ•ด์•ผ ํ• ๊นŒ์š”? ํ•จ๊ป˜ ์•Œ์•„๋ด…์‹œ๋‹ค :)

 

How to solve the problem

React์—์„œ innerHtml๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด dangerouslySetInnerHTML๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

import React from 'react';

function MyComponent() {
  const sampleHtml = '<p>Hello world! </p>';

  return (
    <div dangerouslySetInnerHTML={{ __html: sampleHtml }} />
  );
}

 

์—ฌ๊ธฐ์„œ dangerouslySetInnerHTML์˜ prop ๊ฐ’์œผ๋กœ html ๊ฐ’์„ ์ „๋‹ฌํ•˜๊ณ  ์žˆ๊ณ , ์ด๋Š” __html์ด๋ผ๋Š” ์†์„ฑ์„ ๊ฐ–๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. __html ์†์„ฑ์€ ๋ฆฌ์•กํŠธ์—์„œ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” HTML ๋ฌธ์ž์—ด์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 

 

  • script tag
  • on ์ ‘๋‘์‚ฌ๋ฅผ ๊ฐ€์ง„ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ (ex. onclick, onload)
  • javascript URL (ex. href ์†์„ฑ, src ์†์„ฑ)
  • style ์†์„ฑ 
  • form ํƒœ๊ทธ 

 

์ฃผ์˜์ 

๋ณด์•ˆ ๋ฌธ์ œ ๋•Œ๋ฌธ์— ์‹ ์ค‘ํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋‚ด์šฉ์„ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์•…์„ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๋Š” ๋“ฑ์˜ ๋ณด์•ˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ์ž…๋ ฅ ๊ฐ’์˜ ๋ณด์•ˆ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•ด ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์˜ˆ๋ฐฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

๋ณด์•ˆ ๊ฒ€์‚ฌ ๋ฐฉ๋ฒ•

๋ณด์•ˆ๊ฒ€์‚ฌ ๋ฐฉ๋ฒ•์—๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”, ๋ฆฌ์•กํŠธ์—์„œ๋Š” DOMPurify์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž…๋ ฅ ๊ฐ’์˜ ๋ณด์•ˆ ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์˜ˆ์‹œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. 

import React from 'react';
import DOMPurify from 'dompurify';

function MyComponent({ htmlContent }) {
  const sanitizedHtml = DOMPurify.sanitize(htmlContent);

  return (
    <div dangerouslySetInnerHTML={{ __html: sanitizedHtml }} />
  );
}
๋ฐ˜์‘ํ˜•