Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Функция evalHTML может кому надо. (https://javascript.ru/forum/project/27041-funkciya-evalhtml-mozhet-komu-nado.html)

devote 31.03.2012 23:46

Функция evalHTML может кому надо.
 
Функция выполняет роль обычного setter'а в innerHTML но при этом выполняет скрипты найденные в HTML.

Функция мало кому нужная, но тут попросили написать такую хрень, вот и написал. Если кому надо используйте. Ах да, она еще может работать как jQuery плагин, тоесть если у вас подключен jQuery то можно вызывать ее через jQuery.

var evalHTML = (function(){

	var fn = function( elem, str ) {

		str = str || elem;

		var stack = [], result;
		str = str.replace( /<script(?:[^>]*src="([^"]+)")?[^>]*>([\s\S]*?)<\/script>/gi, function( all, src, scriptText ) {
			stack[ stack.length ] = src ? { src: src } : { script: scriptText };
			return "";
		});

		if ( window.jQuery && this instanceof jQuery ) {
			result = this.html( str );
		} else {
			elem.innerHTML = str;
		}

		for( var i = 0; i < stack.length; i++ ) {

			if ( stack[ i ].src ) {

				var l, script, exists = false,
					head = document.getElementsByTagName( 'head' )[ 0 ],
					scripts = document.getElementsByTagName( 'script' );

				for( l = 0; script = scripts[ l++ ]; ) {
					if ( script.src.indexOf( stack[ i ].src ) != -1 ) {
						exists = true;
						break;
					}
				}

				if ( !exists ) {
					script = document.createElement('script');
					script.src = stack[ i ].src;
					script.type = "text/javascript";
					head.appendChild( script );
				}

			} else {
				( window.execScript || function( data ) {
					window[ "eval" ].call( window, data );
				} )( stack[ i ].script );
			}
		}

		return result;
	}

	if ( window.jQuery ) {
		jQuery.fn.evalHTML = fn;
	}

	return fn;
})();

пример без jQuery:
<div id="view"></div>
<script type="text/javascript">
var evalHTML = (function(){

	var fn = function( elem, str ) {

		str = str || elem;

		var stack = [], result;
		str = str.replace( /<script(?:[^>]*src="([^"]+)")?[^>]*>([\s\S]*?)<\/script>/gi, function( all, src, scriptText ) {
			stack[ stack.length ] = src ? { src: src } : { script: scriptText };
			return "";
		});

		if ( window.jQuery && this instanceof jQuery ) {
			result = this.html( str );
		} else {
			elem.innerHTML = str;
		}

		for( var i = 0; i < stack.length; i++ ) {
			if ( stack[ i ].src ) {
				var head = document.getElementsByTagName( 'head' )[ 0 ],
					script = document.createElement('script');
				script.src = stack[ i ].src;
				script.type = "text/javascript";
				head.appendChild( script );
			} else {
				( window.execScript || function( data ) {
					window[ "eval" ].call( window, data );
				} )( stack[ i ].script );
			}
		}

		return result;
	}

	if ( window.jQuery ) {
		jQuery.fn.evalHTML = fn;
	}

	return fn;
})();

var html = "<b>Жирный текст<script>alert('а я алерт который динамично вставили.');<"+"/script></b>";
evalHTML( document.getElementById( 'view' ), html );

</script>

пример c jQuery:
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<div id="view"></div>
<script type="text/javascript">
var evalHTML = (function(){

	var fn = function( elem, str ) {

		str = str || elem;

		var stack = [], result;
		str = str.replace( /<script(?:[^>]*src="([^"]+)")?[^>]*>([\s\S]*?)<\/script>/gi, function( all, src, scriptText ) {
			stack[ stack.length ] = src ? { src: src } : { script: scriptText };
			return "";
		});

		if ( window.jQuery && this instanceof jQuery ) {
			result = this.html( str );
		} else {
			elem.innerHTML = str;
		}

		for( var i = 0; i < stack.length; i++ ) {
			if ( stack[ i ].src ) {
				var head = document.getElementsByTagName( 'head' )[ 0 ],
					script = document.createElement('script');
				script.src = stack[ i ].src;
				script.type = "text/javascript";
				head.appendChild( script );
			} else {
				( window.execScript || function( data ) {
					window[ "eval" ].call( window, data );
				} )( stack[ i ].script );
			}
		}

		return result;
	}

	if ( window.jQuery ) {
		jQuery.fn.evalHTML = fn;
	}

	return fn;
})();

var html = "<b>Жирный текст<script>alert('а я алерт который динамично вставили.');<"+"/script></b>";

$( "#view" ).evalHTML( html );

</script>

denis_orlov 01.04.2012 12:13

мне надо!
беру две!
спасибо.

Sweet 01.04.2012 13:03

jQuery и так это умеет:
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<div id="view"></div>
<script>
var html = "<b>Жирный текст<script>alert('а я алерт который динамично вставили.');<"+"/script></b>";

$( "#view" ).html( html );
</script>

melky 01.04.2012 13:24

Цитата:

Сообщение от devote (Сообщение 166172)
Функция выполняет роль обычного setter'а в innerHTML но при этом выполняет скрипты найденные в HTML.

Функция мало кому нужная, но тут попросили написать такую хрень, вот и написал. Если кому надо используйте. Ах да, она еще может работать как jQuery плагин, тоесть если у вас подключен jQuery то можно вызывать ее через jQuery.

} else {
				( window.execScript || function( data ) {
					*!*window[ "eval" ].call( window, data );*/!*
				} )( stack[ i ].script );
			}
		}

BAD. Используйте new Function вместо eval, или это :

<body>.....</body>

<script>
var evalString = " document.write('Hello WORLD !!!') ";

var s = document.createElement('script');
s.innerHTML = evalString;
document.body.appendChild(s);
</script>

devote 01.04.2012 14:14

Цитата:

Сообщение от melky
BAD. Используйте new Function вместо eval, или это :

new Function каким способом выполнить в глобальном пространстве? тоесть скрипты то должны в глобалке выполняться...

И вообще чего это вдруг все против евала-то? или я что-то не знаю? его вырежут в будущих версия? или с помощью него можно удалить все файлы у клиента на компе? На серверных языках евал это да, плохо. Но на клиенте почему к нему такое отвращение не пойму.

P.S. Функцию писал не для себя, мне честно говоря все-равно как она евалит.

melky 01.04.2012 17:46

Цитата:

Сообщение от devote (Сообщение 166256)
new Function каким способом выполнить в глобальном пространстве? тоесть скрипты то должны в глобалке выполняться...

И вообще чего это вдруг все против евала-то? или я что-то не знаю? его вырежут в будущих версия? или с помощью него можно удалить все файлы у клиента на компе? На серверных языках евал это да, плохо. Но на клиенте почему к нему такое отвращение не пойму.

P.S. Функцию писал не для себя, мне честно говоря все-равно как она евалит.

Ну, раз все согласились его избегать, значит, стоит его избегать. :) дело вкуса

devote 01.04.2012 18:34

Цитата:

Сообщение от melky
Ну, раз все согласились его избегать, значит, стоит его избегать. дело вкуса

согласились избегать где? на серверных приложениях да избегают все, в том числе и я. Ибо на сервере можно инъекцию сделать в случае евала. И конечно же навредить серверным данным. На стороне клиента евал опасен так же как и alert. То-есть нанести ущерб клиенту на компе не реально.

melky, боюсь вы не совсем точно информацию прочли о проблемах с евалом.

FINoM 13.05.2012 02:33

Цитата:

Сообщение от devote
window[ "eval" ].call( window, data );

А почему не просто eval(data)? Ну или хотя-бы window.eval.call(window,data), почему eval — строка?

devote 13.05.2012 04:09

Цитата:

Сообщение от FINoM
А почему не просто eval(data)? Ну или хотя-бы window.eval.call(window,data), почему eval — строка?

а черт их знает, я этот кусок кода из джуквери выдрал... Для чего они там так сделали это их надо спросить :)

vadim5june 13.05.2012 10:01

Цитата:

Сообщение от Sweet (Сообщение 166236)
jQuery и так это умеет:
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
<div id="view"></div>
<script>
var html = "<b>Жирный текст<script>alert('а я алерт который динамично вставили.');<"+"/script></b>";

$( "#view" ).html( html );
</script>

Что то странное у меня происходит с этим примером-беру меняю id на любое другое и script не выполняется-только html вставляется


Часовой пояс GMT +3, время: 15:16.