Если вы посмотрите немного глубже в исходный код jQuery, мы найдем способ html
.
В этом методе существует следующая line
this.empty().append(value);
Если теперь перейти к append
, мы можем найти следующий
append: function() {
return domManip(this, arguments, function(elem) {
if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
var target = manipulationTarget(this, elem);
target.appendChild(elem);
}
});
}
Итак, теперь найти domManip
. Внутри эту функцию из HTML-строки устроится Фрагмен, и если фрагмент имеет тег сценария выполнение next code
DOMEval(node.textContent.replace(rcleanScript, ""), doc);
Где DOMEval
function DOMEval(code, doc) {
doc = doc || document;
var script = doc.createElement("script");
script.text = code;
doc.head.appendChild(script).parentNode.removeChild(script);
}
Так, по крайней мере, мы находим место, где выполнение сценариев.
Итак, почему в каком-то случае html
запускать скрипт, а иначе нет?
Это зависит от строки ввода и того, что возвращается buildFragment
function.
Внутри buildFragment
мы нашли next line
tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter(elem) + wrap[ 2 ];
где elem
является входной строкой и jQuery.htmlPrefilter
является следующей функцией
htmlPrefilter: function(html) {
return html.replace(rxhtmlTag, "<$1></$2>");
}
так, входная строка просто Заменена с некоторыми regular exporession rxhtmlTag
.
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
Так, просто попробуйте это для проверки строки:
console.log(jQuery.htmlPrefilter("<iframe><iframe //><script>alert(1)</" + "script>"));
console.log(jQuery.htmlPrefilter("<iframe><iframe> // <script>alert(1)</" + "script>"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
Таким образом, в первом случае, как результат был
<iframe><iframe /></iframe><script>alert(1)</script>
И после вставки его как innerHTML в tmp
div, внутри div create два элементов: iframe и скрипт. Таким образом, после этого сценария, доступных для поиска и выполнения
Во втором случае:
<iframe><iframe> // <script>alert(1)</script>
Строка не изменилась, а после вставки ее как innerHTML в tmp
DIV внутри DIV создать только один элемент IFrame с кодированным контентом. Вот почему в этом случае скрипт не выполняется.
'//' не является комментарием html ... они выглядят как '' – charlietfl
И закрывающий тег тоже ошибочен – Bharat
@BharatPatidar Я знаю, что это неправильно. Но для этого искаженного HTML-кода, почему это различие между .innerHTML() и JQuery .html()? –