티스토리 뷰

 

 

 

innerHTML, innerText, textContent 이 셋의 차이점 찾아보다가 innerHTML의 위험성이라는 글을 보게 되었고.. innerHTML만 써왔던 사람으로서 insertAdjacentHTML의 필요성을 몰랐기 때문에 정리 해보려 한다.

 

따라서 이번 포스팅에서는 innerHTML의 위험성과 더불어 HTML 요소를 추가할 수 있는 또 다른 방법인 insertAdjacentHTML메서드에 대해 다룰 것이다.

 

 

 

1. innerHTML


innerHTML 프로퍼티는 HTML에 새로운 HTML 요소를 추가하거나 특정 HTML 요소 내부에 작성된 내용(HTML 요소를 포함)을 가져오는 데 사용한다. 

 

구문

element.innerHTML( text )

 

 

예시


아래는 간단한 HTML 마크업이다.

<div class="content">
  <h1>category</h1>
  <ul>
    <li>li-1</li>
    <li>li-2</li>
  </ul>
</div>

 

 

 

아래는 class가 "content"인 HTML 요소를 접근한 다음 innerHTML 프로퍼티의 값을 콘솔에 출력하는 JavaScript 코드이다.

 

순서 1. getElementById() 또는 querySelector() 메서드를 사용하여 class가 "content"인 HTML 요소를 접근한다.

순서2. getElementById() 또는 querySelector() 메서드 반환 결과에서 innerHTML 프로퍼티를 호출한다.

const content = document.getElementById("content");

console.log(content.innerHTML);

 

 

실행 결과는 다음과 같다.

<h1>category</h1>
<ul>
    <li>li-1</li>
    <li>li-2</li>
</ul>

 

실행 결과에서 알 수 있듯이 innerHTML 프로퍼티는 class가 "content"인 <div> 태그 안의 HTML 요소가 포함된 내용을 가져온다. 만약 <div> 태그 안의 텍스트만 가져오고 싶다면 innerText 또는 textContent 프로퍼티를 사용하면 된다.

 

정리하자면, HTML 요소를 가져온 다음 innertHTML 프로퍼티의 값을 변경하면 HTML 요소의 텍스트를 변경하거나 하위 노드를 추가할 수 있다.

 

 

2. innerHTML의 위험성


innerHTML의 사용법은 매우 간단하다. 하지만 이 프로퍼티는 성능 및 보안이 취약하다는 몇 가지 문제가 있다.

 

 

1. 매우 느리다.

 

innerHTML 프로퍼티의 값을 변경하면 innerHTML 프로퍼티를 호출한 노드를 삭제 후 재구성한다. 위 예제로 설명하자면 <div> 요소를 삭제한 다음 innerHTML 프로퍼티의 값이 적용된 <div> 요소를 다시 표현한다.

 

간단한 HTML 문서에서 innerHTML 프로퍼티를 사용하면 큰 문제가 되지 않을 수 있지만, 복잡한 HTML 문서에서는 노드를 재구성하는 데 시간이 많이 걸리고 의도하지 않은 부작용이 발생할 수 있다.

 

2. 기존 이벤트 리스너를 제거한다.

 

innerHTML 이전에 설정된 이벤트 리스너를 제거한다. 한마디로 노드를 삭제 후 재구성하는 과정에서 이벤트 리스너가 손실된다.

 

3. XSS

 

innerHTML를 사용하면 악의적인 사용자가 XSS(Cross-Site Scripting)을 사용하여 개인 사용자 정보를 갈취하거나 악의적은 스크립트를 추가할 수 있다. 

 

XSS란?

XSS(Cross-Site Scripting)은 악의적인 목적을 가진 이가 웹사이트에 악성 스크립트를 주입하는 행위를 말한다.

사용자의 입력을 받기 위해 만들어진 input, textarea와 같은 창에서 누군가가 스크립트를 작성하고, 그 스크립트가 innerHTML과 연결되어 파싱을 거친 뒤 코드단에 주입되면, 관리자가 예상하지 못한 결과가 발생할 수 있다.

스크립트 내용에 따라서 쿠키나 세션 토큰 등의 탈취가 가능해서, 이를 인증이나 세션관리에 사용하고 있는 사이트에 침입하거나 심각한 피해를 입힐 가능성이 있다.

 

 

 

3. insertAdjacentHTML


앞서 말했듯이 innerHTML을 사용하게 되면 기존에 있던 것은 덮어씌워지기 때문에 기존의 값은 보이지 않는다. 하지만 insertAdjacentHTML기존의 값은 건드리지 않는다. 또한 새롭게 내가 입력하고 싶은 값을 어떤 위치에 놓을지까지 설정할 수 있다.

 

추가로 insertAdjacentHTML은 기존 HTML 요소를 손상시키지 않고 텍스트 또는 HTML 요소를 추가하므로 innerHTML 프로퍼티보다 조금 더 빠르게 동작한다.

 

그러나 innerHTML 프로퍼티와 마찬가지로 HTML 마크업 문자열을 파싱하므로 크로스 사이트 스크립팅 공격에 취약하다는 점은 동일하다.

 

 

구문

element.insertAdjacentHTML(position, text);

 

매개변수

 

position: 추가하려는 텍스트 또는 HTML 요소의 위치를 나타내는 문자열이며 아래 네 가지 값( 'beforebegin' , 'afterbegin', 'beforeend', 'afterend' )중 하나를 사용한다.


 

position 의 예시 그림

<!-- beforebegin -->
<p>
<!-- afterbegin -->
foo
<!-- beforeend -->
</p>
<!-- afterend -->



 
innerHTML과 insertAdjacentHTML을 표로 정리하면 다음과 같다.

element.insertAdjacentHTML( position, text ) element.innerHTML( text )
2개의 인자(추가될 위치, html코드)가 필요함 (추가될 위치, html코드) 1개의 인자 필요
지정한 곳에 노드가 추가 될 뿐 기존 노드 건드리지 않음 기존 노드 삭제 후 재구성
첫번재 인자인 "position"에서는 4종류가 있음.
[ beforebegin, afterbegin, beforeend, afterend ]
X

 

 

 

정리


- innerHTML 프로퍼티는 노드를 삭제 후 재구성하므로 복잡한 HTML 문서에서 사용하면 HTML을 재구성하는 데 많은 시간이 소모될 수 있다.

- insertAdjacentHTML() 메서드는 노드를 재구성하지 않고 텍스트 또는 HTML 요소를 원하는 위치에 추가하므로 innerHTML 프로퍼티보다 빠르게 동작한다.