[javascript] 문자열을 자스 코드로 평가하는 짓거리.

여러분은 문자열을 자스 코드로 평가하는 짓거리를 하는 방법을 들라 하면 대표적으로 eval 들겁니다. 

제목이 이따구냐 들어와봤는데 eval 만 들어도 “아” 할거에요. 

근데.. 문자열을 자스 코드로 바꾸는 방법은.. 의외로 다양합니다. 

IE 전용 방법으로는 document.execScript 메서드가 있습니다. 

new Function(arg1,arg2,argN…,functionBody) 에서 functionBody 가 문자열이어도 함수가 만들어지며 자스 코드로 됩니다. 속살은 네이티브이니 eval 쓰는지 알 턱은 없지만.. 

setTimeout(functionBody,millisecond) 함수에 문자열을 코드로 집어넣는거. 옛날에 자스 해봤다면 쉽게 접해봤을 겁니다. 무서운건 지금도 setTimeout 에다가 문자열 집어넣는 선배님도 봤습니다. 우웩. 

네. eval 은 이미 많이 알려진 “악마”고 차기 ECMA 표준에서 뺄거란 얘기가 무성하게 흘러나왔죠. 

eval의 특징은 해당 스코프의 문자열을 자스 코드로 변환하여 실행하는 특징을 가지고 있습니다. 

스코프 뚫리면 보안은 뭐.. 말안해도 섬뜩할겁니다. 

그러다가 jQuery 에서 globalEval 메서드가 있는겁니다. 이녀석의 특징은 일단 문자열을 자스로 평가하는데 스코프를 무조건 최상위인 window로 잡는 특징이 있습니다. 일단 보안 측면에서는 다행이긴 한데 문자열을 자스 코드로 평가하다니.. 

그러다가 globalEval 메서드를 까봤습니다. 

globalEval: function( data ) { 

    if ( data && rnotwhite.test( data ) ) { 

        // We use execScript on Internet Explorer 

        // We use an anonymous function so that context is window 

        // rather than jQuery in Firefox 

        ( window.execScript || function( data ) { 

            window[ “eval” ].call( window, data ); 

        } )( data ); 

    } 

}, 

window 스코프를 가리키는 eval 악마를 보실 수 있습니다.으헝헝. 

이녀석이 왜 있냐구요? 이녀석도 쓰입니다. ajax 에서 스크립트 불러올때 그 스크립트 실행하기 위해 존재하는 메서드죠. 

그런데 말입니다. 

그런데.. 저는 의아해 했습니다. 좀 더 안전하게 스크립트를 실행하는 다른 방법이 있을까. 

그래서 여러가지 실험을 해봤습니다. 아까 new Function 에서 문자열 받아내는거 아시죠? 

그걸 이용해 봤습니다. 

new Function(“console.log(this);”)(); 

이렇게 해봐서 콘솔 봤더니 this 는 window를 가리킵니다. 

그리고 

function foo(){ 

    new Function(“console.log(this)”)(); 

new foo(); 

이렇게도 해봤더니 this는 여전히 window를 가리켰습니다. 

불여우, 크롬, IE 6,8,9,10 모두 같은 결과가 나왔습니다. 

그렇다면 jquery globalEval을 이렇게 꾸며도 무방할것 같다는 생각이 들었습니다. 

globalEval: function( data ) { 

    if ( data && rnotwhite.test( data ) ) { 

        return void new Function(data)(); 

    } 

}, 

게다가 new Function 은 인자도 받을 수 있습니다. (IE는 모르겠지만) 

스코프는 항상 최상위인 window 를 가리킵니다. 

처음엔 이렇게도 생각해봤습니다. 

globalEval: function( data ) { 

    if ( data && rnotwhite.test( data ) ) { 

        return void setTimeout(data,0); 

    } 

}, 

이렇게 하면 IE의 메모리 누수를 막을 수 있을 것 같은 느낌도 들어서죠. 

이번엔 더 거대하게 생각을 해봤습니다. 아예 스크립트 태그를 만들어 버리는 것도요. 

var script = document.createElement(‘script’); 

script.innerHTML=code+’\n’+//자스 코드 넣고 

    ‘var scripts=document.getElementsByTagName(‘script’);\n’+ 

    ‘document.documentElement.removeChild(scripts[scripts.length-1])’;//스크립트 실행후 DOM 삭제 

document.documentElement.appendChild(script); 

이것저것 생각해봤습니다. 

여러분은 타 스크립트를 가져올때 어떤 방법이 가장 좋을까요? 

물론 원격지 스크립트라면 script 태그가 진리겠죠. 

일단 생각해봅시다. 같은 도메인 안에서 한다고 가정하고. 원격 스크립트를 실행하는 방법이죠. 

동적으로 불러와야 한다는 전제 하에. 

  1. 스크립트 파일을 동적으로 만들어 script 태그 하나 만들어 포함시킨다. 

  2. 스크립트 파일을 Ajax로 불러오고 jQuery globalEval 등으로 실행시킨다. 

  3. 내가 테스트한 방법을 써본다 

<

p>

동적 스크립트 실행. 이대로 괜찮은가? 

참으로 어처구니 없는 일이 아닐 수 없습니다.

composite / 2013년 7월 20일 / 미분류
태그:, , , , , ,

답글 남기기

Your email address will not be published / Required fields are marked *