programing

동적으로 로드된 JavaScript 블록을 실행하려면 어떻게 해야 합니까?

muds 2023. 4. 1. 10:07
반응형

동적으로 로드된 JavaScript 블록을 실행하려면 어떻게 해야 합니까?

웹 페이지에서 작업 중인데, 다음과 같은 HTML 청크를 반환하는 AJAX 호출을 하고 있습니다.

<div>
  <!-- some html -->
  <script type="text/javascript">
    /** some javascript */
  </script>
</div>

DOM에 모든 것을 삽입하고 있습니다만, JavaScript가 실행되고 있지 않습니다.작동시킬 방법이 있나요?

상세:스크립트 블록의 내용을 제어할 수 없습니다(따라서 호출 가능한 함수로 변경할 수 없습니다). 블록 전체를 실행하면 됩니다.JavaScript가 HTML의 더 큰 블록 안에 있기 때문에 응답에 대한 평가를 호출할 수 없습니다. 자바스크립트를 분리하여 eval을 호출하는 일종의 regex를 수행할 수 있지만, 그것은 매우 불쾌한 일입니다.더 좋은 방법 아는 사람?

내부 설정을 통해 추가된 스크립트요소의 HTML 속성이 실행되지 않습니다.새 div를 만들고 내부 설정을 시도합니다.HTML을 사용하여 이 새로운 div를 DOM에 추가합니다.예를 들어 다음과 같습니다.

<blocks><헤드><스크립트 타입='text/script'>함수 addScript(){var str = "<script> "여기 있습니다";</script>,var newdiv = document.createElement('div');
newdiv.displacesHTML = str;document.getElementById('target').appendChild(newdiv);
}</script></head><본문><input type="button" value="add script" on click="add Script()"/><div> hello world </div><div id="target"> </div></body></filters>

리액션을 사용하여 div를 채우는 경우에는 regex를 사용할 필요가 없습니다.getElementsByTagName을 사용할 수 있습니다.

div.innerHTML = response;
var scripts = div.getElementsByTagName('script');
for (var ix = 0; ix < scripts.length; ix++) {
    eval(scripts[ix].text);
}

현재 버전의 Firefox, Google Chrome 또는 Safari 브라우저에서는 from@Ed.dos가 동작하지 않지만 동적으로 추가된 스크립트를 호출하기 위해 그의 예를 활용할 수 있었습니다.

필요한 변경은 스크립트를 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에서 사용할 수 있습니다.

대체 방법은 Inner를 사용하여 Ajax 콜로부터의 리턴을 DOM에 덤프하는 것만이 아닙니다.HTML.

각 노드를 동적으로 삽입하면 스크립트가 실행됩니다.

그렇지 않으면 브라우저는 텍스트노드를 삽입하고 있다고 가정하고 스크립트를 무시합니다.

Eval을 사용하는 것은 Javascript VM의 다른 인스턴스를 기동하고 전달된 문자열을 JIT해야 하기 때문에 다소 문제가 있습니다.

가장 좋은 방법은 DOM을 통해 스크립트블록의 내용을 직접 식별하고 평가하는 것입니다.

그래도 조심할게요.오프 사이트 콜의 제한을 극복하기 위해서 이 기능을 실장하고 있는 경우는, 시큐러티의 구멍을 여는 것입니다.

실장하는 것은 무엇이든 XSS에 악용될 수 있습니다.

이 기능을 기본적으로 제공하는 일반적인 Ajax 라이브러리 중 하나를 사용할 수 있습니다.나는 프로토타입을 좋아한다.Ajax 호출의 일부로 evalScripts:true를 추가하면 자동으로 실행됩니다.

위험한 삶을 살고 싶은 분들을 위해:

// This is the HTML with script element(s) we want to inject
var newHtml = '<b>After!</b>\r\n<' +
  'script>\r\nchangeColorEverySecond();\r\n</' +
  'script>';
  
// Here, we separate the script tags from the non-script HTML
var parts = separateScriptElementsFromHtml(newHtml);

function separateScriptElementsFromHtml(fullHtmlString) {
    var inner = [], outer = [], m;
    while (m = /<script>([^<]*)<\/script>/gi.exec(fullHtmlString)) {
        outer.push(fullHtmlString.substr(0, m.index));
        inner.push(m[1]);
        fullHtmlString = fullHtmlString.substr(m.index + m[0].length);
    }
    outer.push(fullHtmlString);
    return {
        html: outer.join('\r\n'),
        js: inner.join('\r\n')
    };
}

// In 2 seconds, inject the new HTML, and run the JS
setTimeout(function(){
  document.getElementsByTagName('P')[0].innerHTML = parts.html;
  eval(parts.js);
}, 2000);


// This is the function inside the script tag
function changeColorEverySecond() {
  document.getElementsByTagName('p')[0].style.color = getRandomColor();
  setTimeout(changeColorEverySecond, 1000);
}

// Here is a fun fun function copied from:
// https://stackoverflow.com/a/1484514/2413712
function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}
<p>Before</p>

언급URL : https://stackoverflow.com/questions/75943/how-do-you-execute-a-dynamically-loaded-javascript-block

반응형