Если вы укажете атрибут src
как часть элемента script
, любой код в самих тегах элемента script
не будет выполнен. Тем не менее, вы можете добавить эту функцию с помощью следующего кода. Я получил эту технику от Крокфорда (я полагаю, что это был он), где он использует ее в своих выступлениях по несвязанной теме рендеринга производительности и асинхронной загрузки скриптов на страницу с этой целью.
JavaScript:
(function() {
// Using inner class example from bobince's answer
var _gat = (function() {
var data= null;
return {
init: function(d) {
console.info("Configuration data: ", d);
data = d;
}
}
})();
// Method 1: Extract configuration by ID (SEE FOOT NOTE)
var config = document.getElementById("my-counter-apps-unique-and-long-to-avoid-collision-id").innerHTML;
// Method 2: search all script tags for the script with the expected name
var scripts = document.getElementsByTagName("script");
for ( var i=0, l=scripts.length; i<l; ++i ) {
if ( scripts[i].src = "some-script.js" ) {
config = scripts[i].innerHTML;
break;
}
}
_gat.init( eval("(" +config+ ")") );
})();
HTML:
<script type="text/javascript" src="some-script.js" id="my-counter-apps-unique-and-long-to-avoid-collision-id">
{some: "foo", config: "bar", settings: 123}
</script>
Оба метода имеют свои недостатки:
Использование уникального и не конфликтующего идентификатора сделает определение правильного элемента скрипта более точным и быстрым; однако это недопустимая разметка HTML4 / XHTML. В HTML5 вы можете определять произвольные атрибуты, так что это не будет проблемой в то время
Этот метод является допустимой разметкой HTML; однако простое сравнение, которое я показал, может быть легко нарушено, если ваш URL-адрес может быть изменен (например, http против https), а более надежный метод сравнения может быть в порядке
Записка о eval
Оба метода используют eval
. Типичная мантра, касающаяся этой особенности, заключается в том, что «Эвал - это зло». Однако это означает, что использование eval
без знания опасностей eval
является злом.
В этом случае, AFAIK, данные, содержащиеся в тегах script
, не подвергаются атаке внедрения, поскольку сценарий eval'ing (показанный код) выполняется, как только этот элемент достигается при разборе HTML-кода в DOM. Сценарии, которые могли быть определены ранее, не могут получить доступ к данным, содержащимся в тегах script
счетчика, так как этот узел не существует в дереве DOM
в момент их выполнения.
Это может быть случай, когда хорошо выполненное время setTimeout
, выполненное из ранее включенного сценария, может работать во время между включением счетчика script
и временем вычисления; однако, это может или не может иметь место, и, если возможно, может быть не так последовательно, в зависимости от загрузки процессора и т. д.
Мораль истории, если вы беспокоитесь об этом, включите не-1043 * IN парсер JSON и используйте его вместо этого.