Notice
Recent Posts
Recent Comments
Link
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Archives
Today
Total
관리 메뉴

성빈

dangerouslySetInnerHTML/html-react-parser 본문

React

dangerouslySetInnerHTML/html-react-parser

성빈나 2024. 8. 6. 17:27

 

글자 사이에 삽입되어 있는 이미지 태그는 어디에 이미지가 들어가는지 표기하기 위한 '이미지 마킹'이다. 이를 라이브러리를 통해서 json파일을 리액트로 렌더링 해서 한번에 처리하면 좋겠지만 우리가 생각한 것처럼 되는 라이브러리를 찾지 못했다. 그래서 이를 정규 표현식으로 직접 파싱해서 우리가 원하는 img 태그로 전환하려 한다. 그렇게 만들게 된 함수는 아래 코드와 같다.

//HTML 문자열에 포함된 <img> 태그를 실제 이미지로 변경하는 함수
  const parseImageTag = (question) => {
    // 정규식을 사용하여 <img src=1> 문자열을 찾는다.
    const imgRegex = /<img\\s+src=1\\s*\\/?>/g;
    // 대체할 이미지 태그로 교체한다.
    return question.replace(imgRegex, '<img src= "~img_url"   
/>');
};

 

imgRegex변수에는 json파일에 <img src = 1/>태그를 찾을 수 있는 정규 표현식 '/<img\s+src=1\s*\/?>/g'인 문자를 문자열로 기입 해주고 변환이 이루어질 json의 question문자열을 파라매터로 가지고 와 replace를 통해서 imRegex와 내가 윈하는 img 태그로 전환을 해준다.

 

<ol>
        {data.map((item, index) => (
          <li key={index}>
            {/* 질문 */}
             <p dangerouslySetInnerHTML={{ __html: parseImageTag(item.question) }} />
            {/* 4선지 */}
            {item.options.map((option, index) => (
              <div key={index}>{option}</div>
            ))}
          </li>
        ))}
      </ol>

 

여기서 'dangerouslySetInnerHTML'와 ' __html:' 문법은 문자열을 html로 렌더링 할 수 있게 전환 문법이다. dangerouslySetInnerHTML을 찾아보니 React 문법이며, HTML을 동적으로 렌더링하기 위한 용도로 사용된다. 주로 사용되는 상황은 서버에서 가져온 텍스트 데이터에 HTML 태그가 포함되어 있는 경우 그렇다. 이 문법을 사용하지 않으면 다른 문제 사항을 야기 할 수 있는데 React에서는 HTML 태그를 직접 렌더링할 경우 보안상의 이유로 기본적으로 허용하지 않는다. 하지만 dangerouslySetInnerHTML 속성을 사용하면 React가 HTML을 안전하게 렌더링하도록 허용할 수 있다.

따라서 주의해야 할 것은 dangerouslySetInnerHTML을 사용할 때 사전에 신뢰할 수 있는 소스에서 받은 HTML 코드를 렌더링할 때에만 사용해야 한다. 사용자 입력이나 외부에서 가져온 데이터를 이를 통해 렌더링하는 것은 보안상의 위험이 있을 수 있다. 사용 시에는 꼭 취약점에 대한 검토를 거쳐야 한다.

dangerouslySetInnerHTML을 사용하지 않고 html을 어떻게 렌더링 할 수 있는지 고민하다 찾은 라이브러리가 html-react-parser이다. 적용된 코드는 아래와 같다.

 

import parse from 'html-react-parser'; // html-react-parser 모듈 사용
  ...
//HTML 문자열에 포함된 <img> 태그를 실제 이미지로 변경하는 함수
  const parseImageTag = (question, question_img_url) => {
    // 정규식을 사용하여 <img src=1> 문자열을 찾는다.
    const imgRegex = /<img.*?\\/?>/g;
    // 대체할 이미지 태그로 교체한다.
    return question.replace(imgRegex, `<img src="${question_img_url} />`);
  };
 
<ol>
     {data.map((item, index) => (
          <li key={index}>
            {/* 질문 */}
            <p>{parse(parseImageTag(item.question, item.image))}</p>
            {/* 4선지 */}
            {item.options.map((option, index) => (
              <div key={index}>{option}</div>
            ))}
          </li>
        ))}
</ol>

 

기존과 달리 <p dangerouslySetInnerHTML={{ __html: … }} />를 삭제하고 <p>{parse(parseImageTag(item.question, item.image))}</p> 이와 같은 코드를 작성하면 안전하게 html을 렌더링 하게 된다.