그러나 innerHTML에는 그 자체로 몇 가지 문제가 있다는 점을 알아야 합니다.
1. HTML 문자열에 defer로 표시된 스크립트 태그(
)가 포함되어 있을 때 innerHTML 속성이 제대로 처리되지 않으면 Internet Explorer에 나타나 스크립트 삽입 공격을 유발합니다.
2. innerHTML을 설정하면 이벤트 핸들러를 등록한 기존 HTML 요소가 삭제되어 일부 브라우저에서 메모리 누수 위험이 발생할 수 있습니다.
언급할 만한 몇 가지 사소한 단점이 있습니다:
1. 방금 생성한 요소에 대한 참조를 얻을 수 없으며 해당 참조를 얻으려면 수동으로 코드를 추가해야 합니다(DOM 사용). 아피스).
2. 모든 브라우저에서 모든 HTML 요소에 innerHTML 속성을 설정할 수 없습니다(예를 들어 Internet Explorer에서는 테이블의 행 요소에 innerHTML 속성을 설정할 수 없습니다).
innerHTML 속성 사용과 관련된 보안 및 메모리 문제가 더 걱정됩니다. 분명히 이것은 새로운 문제가 아니며 이러한 문제 중 일부에 대한 해결책을 찾아낸 재능 있는 사람들이 이미 있습니다.
Douglas Crockford는 HTML 요소 등록 이벤트 핸들러로 인해 발생하는 일부 순환 참조를 중단하고 가비지 수집기(가비지 수집기)가 이러한 HTML 요소와 연결된 메모리를 해제할 수 있도록 하는 정리 기능을 작성했습니다.
<script>…</script> HTML 문자열에서 스크립트 태그를 제거하는 것은 보기만큼 쉽지 않습니다. 정규식을 사용하면 원하는 효과를 얻을 수 있지만 모든 가능성을 포괄하는지 여부는 알기 어렵습니다.내 해결책은 다음과 같습니다.
/<script>]*>[Ss]*?</script>[^>]*>/ig
이제 이 두 기술을 단일 setInnerHTML 함수로 결합하고 setInnerHTML 함수를 YUI의 YAHOO.util.Dom:
YAHOO.util.Dom.setInnerHTML = function (el, html) {
el = YAHOO.util.Dom.get(el )
if (!el | | typeof html !== 'string') {
return null;
}
// 순환 참조 중단
(function (o) {
var a = o.attributes , i, l, n, c;
if (a) {
l = a.length
for (i = 0; i n = a [i].name;
if (o[n] 유형 === '함수') {
o[n] = null;
> 에 대해 (i = 0; 나는 c = o.childNodes[i];
// 하위 노드 지우기
인수.callee(c);
YUI를 통해 요소의 모든 리스너를 등록합니다. addListener > // HTML 문자열에서 스크립트를 제거하고 innerHTML 속성을 설정합니다.
el.innerHTML = html.replace(/
]*>[Ss]*?]*>/ig, "" ; 공식에 빠진 부분이 있으면 알려주세요.
웹페이지에 악성 코드를 삽입하는 방법은 이 외에도 많습니다. setInnerHTML 함수는 모든 A급 브라우저에서
태그의 실행 동작만 정규화합니다. 신뢰할 수 없는 HTML 코드를 삽입하려면 먼저 서버 측에서 필터링해야 합니다. 이를 수행할 수 있는 라이브러리가 많이 있습니다.