[javascript] <script> 태그를 document.write ()로 쓸 때 왜 분리합니까?

일부 사이트 (또는 클라이언트에 자바 스크립트 코드를 제공하는 광고주)가 통화 내에서 태그 <script>및 / 또는 </script>태그 를 분할하는 기술을 사용하는 이유는 무엇 document.write()입니까?

예를 들어 아마존도이 작업을 수행합니다.

<script type='text/javascript'>
  if (typeof window['jQuery'] == 'undefined') document.write('<scr'+'ipt type="text/javascript" src="http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js"></sc'+'ript>');
</script>



답변

</script>그렇지 않으면 <script></script>엔 클로징 블록이 너무 일찍 종료되므로 분리해야 합니다. 정말로이 나뉘어 있어야 <하고 /스크립트 블록이되도록 (SGML)에 따라 예상되기 때문에, 임의의 종료 태그 열기 (ETAGO) 시퀀스 (즉, 종료 </) :

STYLE 및 SCRIPT 요소는 데이터 모델에 CDATA를 사용하지만 이러한 요소의 경우 사용자 에이전트가 CDATA를 다르게 처리해야합니다. 마크 업 및 엔터티는 원본 텍스트로 처리하고 그대로 응용 프로그램에 전달해야합니다. 문자 시퀀스 ” </“(end-tag open delimiter) 의 첫 번째 항목은 요소 내용의 끝을 종료하는 것으로 간주됩니다. 유효한 문서에서 이는 요소의 종료 태그입니다.

그러나 실제로 브라우저는 실제 </script>닫기 태그 에서 CDATA 스크립트 블록 구문 분석 만 종료 합니다.

XHTML에는 스크립트 블록에 대한 특별한 처리가 없으므로 그 안에 있는 <(또는 &) 문자는 &escaped;다른 요소와 같아야합니다 . 그러나 XHTML을 구식 HTML로 구문 분석하는 브라우저는 혼란 스러울 것입니다. CDATA 블록과 관련된 해결 방법이 있지만 이스케이프 처리되지 않은 문자를 사용하지 않는 것이 가장 쉽습니다. 두 가지 유형의 파서 모두에서 작동하는 스크립트에서 스크립트 요소를 작성하는 더 좋은 방법은 다음과 같습니다.

<script type="text/javascript">
    document.write('\x3Cscript type="text/javascript" src="foo.js">\x3C/script>');
</script>


답변

다음은 이스케이프 형식없이 스크립트 태그를 인라인으로 생성 (즉시 실행) 할 때 사용한 또 다른 변형입니다.

<script>
    var script = document.createElement('script');
    script.src = '/path/to/script.js';
    document.write(script.outerHTML);
</script>

(참고 : 대부분의 인터넷 예제와는 달리 type="text/javascript", 둘러싼 태그 나 생성 된 태그를 설정하지 않았습니다 : 기본적으로 브라우저가 없으므로 중복되지 않지만 아프지 않습니다. 동의하지 않으면).


답변

브라우저의 HTML 파서가 <script>와 주로 </ script>를 실제 스크립트의 닫는 태그로 해석하지 못하도록하기위한 것이라고 생각하지만 document.write를 사용하는 것이 스크립트를 평가하는 훌륭한 아이디어라고 생각하지 않습니다 블록, 왜 DOM을 사용하지 않습니까?

var newScript = document.createElement("script");
...


답변

Bobince가 게시 한 솔루션은 완벽하게 작동합니다. 나는 미래의 방문객들에게도 대안을 제시하고 싶었다

if (typeof(jQuery) == 'undefined') {
    (function() {
        var sct = document.createElement('script');
        sct.src = ('https:' == document.location.protocol ? 'https' : 'http') +
          '://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js';
        sct.type = 'text/javascript';
        sct.async = 'true';
        var domel = document.getElementsByTagName('script')[0];
        domel.parentNode.insertBefore(sct, domel);
    })();
}

이 예제에서는 유스 케이스를 보여주기 위해 jQuery에 대한 조건부로드를 포함시켰다. 누군가에게 도움이 되길 바랍니다!


답변

</script>자바 스크립트 문자열 litteral 내부가 예기치 않은 동작을 일으키는 닫는 태그로 HTML 파서에 의해 해석됩니다 ( JSFiddle에 예 참조 ).

이것을 피하기 위해 주석 사이에 자바 스크립트를 배치 할 수 있습니다 (이 스타일의 코딩은 브라우저에서 Javascript가 제대로 지원되지 않았던 일반적인 관행이었습니다). 이것은 작동합니다 ( JSFiddle의 예제 참조 ).

<script type="text/javascript">
    <!--
    if (jQuery === undefined) {
        document.write('<script type="text/javascript" src="http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js"></script>');
    }
    // -->
</script>

…하지만 솔직히 말해서 사용하는 document.write것이 모범 사례라고 생각 하는 것이 아닙니다. 왜 DOM을 직접 조작하지 않습니까?

<script type="text/javascript">
    <!--
    if (jQuery === undefined) {
        var script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', 'http://z-ecx.images-amazon.com/images/G/01/javascripts/lib/jquery/jquery-1.2.6.pack._V265113567_.js');
        document.body.appendChild(script);
    }
    // -->
</script>


답변