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 вставляется

Kolyaj 13.05.2012 10:37

Цитата:

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

Почти все обфускаторы впадают в коматоз, когда видят eval. Так его прячут от обфускатора, заведомо зная, что eval ничего не сломает в обфусцированном коде.

B@rmaley.e><e 13.05.2012 10:46

Цитата:

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

Избегать eval путём использования new Function? И какой смысл тогда в этом?
Цитата:

Сообщение от http://www.jslint.com/lint.html
eval is evil

The eval function (and its relatives, Function, setTimeout, and setInterval) provide access to the JavaScript compiler. This is sometimes necessary, but in most cases it indicates the presence of extremely bad coding. The eval function is the most misused feature of JavaScript.

Цитата:

Сообщение от devote
На стороне клиента евал опасен так же как и alert. То-есть нанести ущерб клиенту на компе не реально.

Смотря где и как его использовать. Пример:
Есть приложение, получающее откуда-нибудь JSON. И парсится этот JSON не с помощью JSON.parse, а с помощью eval'а. Тогда злоумышленник, получив доступ к скрипту, отдающему этот JSON, может вернуть что-нибудь вроде
(function () {
	/* some code stealing your cookie */
}(), { /*some json data*/ })
Цитата:

Сообщение от FINoM
А почему не просто eval(data)?

Тогда контекст будет захвачен.
(function(){
  var a = 5;
  eval("alert(typeof a)");
  window.eval("alert(typeof a)");
})()

Gozar 13.05.2012 11:23

Цитата:

Сообщение от B@rmaley.e><e
Есть приложение, получающее откуда-нибудь JSON. И парсится этот JSON не с помощью JSON.parse, а с помощью eval'а.

Не давайте детям в руки оголенные провода под напряжением. А если они уже взяли, то им ничем не поможешь.

devote 13.05.2012 12:26

Цитата:

Сообщение от B@rmaley.e><e
Смотря где и как его использовать. Пример:

Соглашусь с Gozar, никакой отказ от использования eval не спасет от криворукого программиста, да и вообще от кривых рук и головы.

devote 13.05.2012 12:34

Цитата:

Сообщение от Kolyaj
Почти все обфускаторы впадают в коматоз, когда видят eval. Так его прячут от обфускатора, заведомо зная, что eval ничего не сломает в обфусцированном коде.

не знаю каким вы пользуетесь обфускатором, но я пользуюсь Closure Compiler и что-то ни разу не видел что бы он плюнул в ответ на то что я где то пихну eval, хотя часто юзаю такую конструкцию:
var msie = eval("/*@cc_on (@_jscript_version+'').replace(/\\d\\./, '');@*/");
почему не юзаю так:
var msie = /*@cc_on (@_jscript_version+'').replace(/\d\./, '');@*/
потому что обфускатор вырезает этот код, так как считает его обычным комментарием.

Kolyaj 13.05.2012 13:35

Цитата:

Сообщение от devote
не знаю каким вы пользуетесь обфускатором, но я пользуюсь Closure Compiler и что-то ни разу не видел что бы он плюнул в ответ на то что я где то пихну eval, хотя часто юзаю такую конструкцию:

Слово "почти" видишь в процитированном сообщении?

devote 13.05.2012 13:39

Цитата:

Сообщение от Kolyaj
Слово "почти" видишь в процитированном сообщении?

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

Kolyaj 13.05.2012 13:50

Вот яховский абсолютно точно переставал сжимать. Может быть в каком-то режиме. Он не ругался, он просто не сжимал ту часть, куда мог залезть eval.

karnas 30.09.2012 11:40

...

Gozar 30.09.2012 13:50

karnas,
Покажи мне место в твоем скрипте где есть evalHTML.

karnas 30.09.2012 13:59

я не знаю куда и как правильно его поставить )) поставил бы его на переменную content , но там уже нет скриптов.

karnas 30.09.2012 15:23

Хоть советом помогите, как в моем варианте выдачи подключить evalHTML()
console.log($(data).find("#newc").html()); тоже выводит уже код без javascript, видимо обрезка идет при передаче контента в url - url: $(this).attr('href'); а вот как избежать вырезания скриптов на этом этапе я не могу понять..

Gozar 30.09.2012 17:27

karnas,
Давай ты приложишь чуть больше усилий, чем просто попрошайничать на форуме?! Мне скучно, как я думаю и другим тоже, выяснять что с тобой не так. Поэтому я просто процетирую свое предыдущее сообщение:

Цитата:

Сообщение от Gozar
karnas,
Покажи мне место в твоем скрипте где есть evalHTML.

Мне лень лепить тебе RTFM, хотя ты подходишь аж под два сразу, так что давай начнем с показа.

karnas 30.09.2012 18:02

Вообще то я по русски изложил ответ на этот вопрос. Я сказал, что в данной ситуации не знаю как использовать evalHTML().
Спасибо за помощь.

Gozar 30.09.2012 18:17

Цитата:

Сообщение от karnas
Вообще то я по русски изложил ответ на этот вопрос.

А по китайски слабо?

Цитата:

Сообщение от karnas
Я сказал, что в данной ситуации не знаю как использовать evalHTML().

Печалька :cray: Поэтому ты хочешь, чтобы это сделал я или кто-то другой?! Ну что же, тогда добро пожаловать в раздел работа. Тебе там с удовольствием помогут за деньги, раз ты сам не в состоянии показать
Цитата:

Сообщение от Gozar
мне место в твоем скрипте где есть evalHTML.

Ну и на тебе RTFM:
Здравствуйте!

Судя по вашему сообщению, вы ну совсем не знаете javascript.

Освойте основы языка и вопрос отпадет сам, полностью или частично.
А с чем не справитесь - поможем.

На сайте javascript можно начать изучать с учебника, раздел Основы javascript.
Возможно, вам также понадобится HTML - учебник есть, например, здесь: http://ru.html.net/tutorials/html/

Задавайте конкретные вопросы по ходу дела.

Gozar 30.09.2012 18:19

http://phpclub.ru/faq/WhyForum

karnas 30.09.2012 20:08

Да уж, клоуны есть везде.. Тут похоже особо тяжкий случай.

Nekromancer 30.09.2012 21:49

Цитата:

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

Они типо там и выполняются. new Function(code) не захватывает контекст.
var a = 1;
(function() {
var a = 2;
(new Function('alert(a)')());
}());

karnas 30.09.2012 22:37

Всем спасибо, решил проблему регуляркой без данного плагина. Почистите пожалуйста срач с темы...

Gozar 01.10.2012 00:15

Цитата:

Сообщение от karnas
Почистите пожалуйста срач с темы...

Зачем нам подчищать за тобой срач, прибирай за собой сам клоун.

karnas 01.10.2012 08:06

Цитата:

Сообщение от Gozar (Сообщение 207402)
Зачем нам подчищать за тобой срач, прибирай за собой сам клоун.

По моему ваша клоунада вас не красит уважаемый, и данный сайт тем более..

Gozar 01.10.2012 11:27

Цитата:

Сообщение от karnas
По моему ваша клоунада вас не красит уважаемый

Мсье зануда?


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