나는 다음과 같은 HTML 덩어리를 반환하는 AJAX 호출하는 웹 페이지에서 일하고 있습니다.
<div>
<!-- some html -->
<script type="text/javascript">
/** some javascript */
</script>
</div>
DOM에 모든 것을 삽입하고 있지만 JavaScript가 실행되고 있지 않습니다. 그것을 실행할 수있는 방법이 있습니까?
일부 세부 정보 : 스크립트 블록의 내용을 제어 할 수 없으므로 호출 할 수있는 기능으로 변경할 수 없으므로 전체 블록을 실행하면됩니다. JavaScript가 더 큰 HTML 블록 내에 있기 때문에 응답에 대해 eval을 호출 할 수 없습니다. JavaScript를 분리하고 eval을 호출하기 위해 일종의 정규 표현식을 수행 할 수는 있지만 꽤 유쾌합니다. 더 나은 방법을 아는 사람이 있습니까?
요소의 innerHTML 속성을 설정하여 추가 된 스크립트는 실행되지 않습니다. 새 div를 만들고 innerHTML을 설정 한 다음이 새 div를 DOM에 추가하십시오. 예를 들면 다음과 같습니다.
<html> <head> <script type = 'text/javascript'> function addScript () { var str = "<script> alert ( 'i am here'); <\/script>"; var newdiv = document.createElement ( 'div'); newdiv.innerHTML = str; document.getElementById ( 'target'). appendChild (newdiv); } </ script> </ head> <body> <입력 유형 = "button"value = "add 스크립트"onclick = "addScript ()"/> <div> hello world </ div> < div id = "target"> </ div> </ body> </ html>
응답을 사용하여 div 또는 무언가를 채우는 경우 정규식을 사용할 필요가 없습니다. getElementsByTagName을 사용할 수 있습니다.
div.innerHTML = response;
var scripts = div.getElementsByTagName('script');
for (var ix = 0; ix < scripts.length; ix++) {
eval(scripts[ix].text);
}
@Ed.의 답변은 받아 들였습니다. Firefox의 현재 버전, Google Chrome 또는 Safari 브라우저에서 작동하지 않습니다. 동적으로 추가 된 스크립트를 호출하기 위해 그의 예제를 능숙하게 관리했습니다.
필요한 변경 사항은 스크립트가 DOM에 추가되는 방식에만 있습니다. 트릭은 innerHTML
로 추가하는 대신 새 스크립트 요소를 작성하고 실제 스크립트 컨텐츠를 innerHTML
로 작성된 요소에 추가 한 후 스크립트 요소를 실제 대상에 추가하는 것이 었습니다.
<html>
<head>
<script type='text/javascript'>
function addScript()
{
var newdiv = document.createElement('div');
var p = document.createElement('p');
p.innerHTML = "Dynamically added text";
newdiv.appendChild(p);
var script = document.createElement('script');
script.innerHTML = "alert('i am here');";
newdiv.appendChild(script);
document.getElementById('target').appendChild(newdiv);
}
</script>
</head>
<body>
<input type="button" value="add script" onclick="addScript()"/>
<div>hello world</div>
<div id="target"></div>
</body>
</html>
Firefox 42, Google Chrome 48 및 Safari 9.0.3)에서 작동합니다.
대안은 InnerHTML을 사용하여 Ajax 호출에서 DOM으로 리턴을 덤프하지 않는 것입니다.
각 노드를 동적으로 삽입하면 스크립트가 실행됩니다.
그렇지 않으면 브라우저는 텍스트 노드를 삽입한다고 가정하고 스크립트를 무시합니다.
Eval을 사용하는 것은 Javascript VM의 다른 인스턴스를 실행하고 전달 된 문자열을 JIT해야하기 때문에) 다소 악의적입니다.
가장 좋은 방법은 아마도 스크립트 블록의 내용을 DOM을 통해 직접 확인하고 평가하는 것입니다.
하지만 조심해야 할 것입니다. 오프 사이트 호출의 한계를 극복하기 위해 이것을 구현하는 경우 보안 허점이 생깁니다.
XSS를 위해 구현 한 것이 무엇이든 이용할 수 있습니다.
기본적으로이 작업을 수행하는 인기있는 Ajax 라이브러리 중 하나를 사용할 수 있습니다. 시제품 을 좋아합니다. Ajax 호출의 일부로 evalScripts : true를 추가하면 자동으로 발생합니다.