[javascript] AJAX 호출 후 innerHTML에 의해 주입 된 <script> 실행

“Content”라는 div가 있습니다.

<div id="content"></div>

<script>태그를 포함하여 AJAX에 의해 PHP 파일의 데이터로 채워 져야합니다 . 그러나이 태그 내의 스크립트는 실행되지 않습니다.

<div id="content"><!-- After AJAX loads the stuff that goes here -->
   <script type="text/javascript">
     //code
   </script>
   <!-- More stuff that DOES work here -->
</div>



답변

DOM 텍스트로 삽입 된 JavaScript는 실행되지 않습니다. 그러나 동적 스크립트 패턴 을 사용하여 목표를 달성 할 수 있습니다 . 기본 아이디어는 실행할 스크립트를 외부 파일로 이동하고 Ajax 응답을받을 때 스크립트 태그를 만드는 것입니다. 그런 다음 src스크립트 태그 및 짜잔 의 속성 을 설정 하면 외부 스크립트를로드하고 실행합니다.

이 다른 StackOverflow 게시물도 도움이 될 수 있습니다. 스크립트를 innerHTML로 삽입 할 수 있습니까? .


답변

이 코드를 사용했는데 잘 작동합니다.

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div


답변

다음과 같이 Ajax를 통해 div 내에서 스크립트 블록을로드하는 경우 :

<div id="content">
    <script type="text/javascript">
    function myFunction() {
      //do something
    }
    myFunction();
    </script>
</div>

… 페이지의 DOM을 업데이트하기 만하면 myFunction ()이 반드시 호출되는 것은 아닙니다.

jQuery의 ajax () 메서드에 있는 것과 같은 Ajax 콜백 메서드를 사용하여 요청이 완료 될 때 실행할 항목을 정의 할 수 있습니다.

당신이하는 일은 처음부터 자바 스크립트가 포함 된 페이지를 로딩하는 것과는 다릅니다 (실행되는).

일부 콘텐츠를 가져온 후 성공 콜백 및 오류 콜백을 사용하는 방법의 예 :

  $.ajax({
    type: 'GET',
    url: 'response.php',
    timeout: 2000,
    success: function(data) {
      $("#content").html(data);
      myFunction();
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
      alert("error retrieving content");
    }

또 다른 빠르고 더러운 방법은 jQuery 또는 기타 라이브러리를 사용하지 않으려는 경우 eval () 을 사용 하여 DOM 텍스트로 삽입 한 스크립트 코드를 실행하는 것입니다.


답변

다음은 텍스트의 모든 스크립트 태그를 평가하는 스크립트입니다.

function evalJSFromHtml(html) {
  var newElement = document.createElement('div');
  newElement.innerHTML = html;

  var scripts = newElement.getElementsByTagName("script");
  for (var i = 0; i < scripts.length; ++i) {
    var script = scripts[i];
    eval(script.innerHTML);
  }
}

서버에서 HTML을받은 후에이 함수를 호출하십시오. 경고 : 사용 eval은 위험 할 수 있습니다.

데모 :
http://plnkr.co/edit/LA7OPkRfAtgOhwcAnLrl?p=preview


답변

이것은 문서에 XHR 반환 HTML의 하위 집합을 추가하지 않는 경우 jQuery를 사용하여 ‘그냥 작동합니다’. ( jQuery의 문제를 보여주는 이 버그 보고서 를 참조하십시오 .)

다음은 작동을 보여주는 예입니다.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>test_1.4</title>
    <script type="text/javascript" charset="utf-8" src="jquery.1.4.2.js"></script>
    <script type="text/javascript" charset="utf-8">
        var snippet = "<div><span id='a'>JS did not run<\/span><script type='text/javascript'>" +
        "$('#a').html('Hooray! JS ran!');" +
        "<\/script><\/div>";
        $(function(){
            $('#replaceable').replaceWith($(snippet));
        });
    </script>
</head>
<body>
    <div id="replaceable">I'm going away.</div>
</body>
</html>

위의 내용은 다음과 같습니다. http://jsfiddle.net/2CTLH/


답변

다음은 AJAX 응답을 구문 분석하는 데 사용할 수있는 함수입니다. 특히 minifiedjs를 사용하고 반환 된 Javascript를 실행하거나 DOM에 추가하지 않고 스크립트를 구문 분석하려는 경우 예외 오류도 처리합니다. 이 코드를 php4sack 라이브러리에서 사용했으며 라이브러리 외부에서 유용합니다.

function parseScript(_source) {
    var source = _source;
    var scripts = new Array();

    // Strip out tags
    while(source.toLowerCase().indexOf("<script") > -1 || source.toLowerCase().indexOf("</script") > -1) {
        var s = source.toLowerCase().indexOf("<script");
        var s_e = source.indexOf(">", s);
        var e = source.toLowerCase().indexOf("</script", s);
        var e_e = source.indexOf(">", e);

        // Add to scripts array
        scripts.push(source.substring(s_e+1, e));
        // Strip from source
        source = source.substring(0, s) + source.substring(e_e+1);
    }

    // Loop through every script collected and eval it
    for(var i=0; i<scripts.length; i++) {
        try {
          if (scripts[i] != '')
          {
            try  {          //IE
                  execScript(scripts[i]);
      }
      catch(ex)           //Firefox
      {
        window.eval(scripts[i]);
      }

            }
        }
        catch(e) {
            // do what you want here when a script fails
         // window.alert('Script failed to run - '+scripts[i]);
          if (e instanceof SyntaxError) console.log (e.message+' - '+scripts[i]);
                    }
    }
// Return the cleaned source
    return source;
 }


답변

스크립트 태그가 필요한 것을 주입하는 경우 잡히지 않은 구문 오류가 발생하고 불법 토큰이라고 말할 수 있습니다. 이를 방지하려면 닫는 스크립트 태그에서 슬래시를 이스케이프해야합니다. 즉;

var output += '<\/script>';

양식 태그와 같은 닫는 태그도 마찬가지입니다.