jQuery: анализировать / манипулировать HTML без выполнения сценариев - PullRequest
4 голосов
/ 22 мая 2009

Я загружаю HTML через Ajax в следующем формате:

<div id="div1">
  ... some content ...
</div>
<div id="div2">
  ...some content...
</div>
... etc.

Мне нужно перебирать каждый div в ответе и обрабатывать его отдельно. Наличие отдельной строки для содержимого HTML каждого div, сопоставленного с идентификатором, удовлетворит мои требования. Тем не менее, div может содержать теги сценария, которые мне нужно сохранить, но не выполнить (они будут выполнены позже, когда я вставлю HTML-код в документ, поэтому выполнение во время синтаксического анализа будет плохим). Моей первой мыслью было сделать что-то вроде этого:

// data being the result from $.get
var clean = data.replace(/<script.*?</script>/,function() {
    // insert some unique token, save the tag, put it back while I'm processing
}); 

$('<div/>').html(clean).children().each( /* ... process here ... */);

Но я волнуюсь, что придет какой-нибудь глупый разработчик и поместит что-то вроде этого в один из div:

<script> var foo = '</script>'; // ... </script>

Что бы все испортить. Не говоря уже о том, что все это похоже на взлом с самого начала. Кто-нибудь знает лучший способ?

РЕДАКТИРОВАТЬ: Вот решение, которое я придумал:

var divSplitRegex = /(?:^|<\/div>)\s*<div\s+id="prefix-(.+?)">/g,
    idReplacement = preDelimeter+'$1'+postDelimeter;
var r = data.replace(<\/div>\s*$/,'').
    replace(divSplitRegex,idReplacement).split(preDelimeter);
$.each(r,function() {
    var content;
    if(this) {
        callback.apply(null,this.split(postDelimeter));
    }
});

Где preDelimiter и postDelimeter - это просто уникальные строки, такие как "### Я должен быть идиотом, чтобы встраивать эту строку в мой контент без экранирования, потому что он сломает все ### ', а callback - это функция, ожидающая div id и содержимое div. Это работает только потому, что я знаю, что div будет иметь только атрибут id, а id будет иметь специальный префикс. Я предполагаю, что кто-то может добавить div в свой контент с идентификатором, имеющим тот же префикс, и тоже все испортил.

Итак, я до сих пор не люблю это решение. У кого-нибудь есть лучший?

Ответы [ 3 ]

3 голосов
/ 22 мая 2009

FYI, использование unesceded в любом скрипте JavaScript вызывает эту проблему в браузере В любом случае разработчики должны избежать этого, поэтому нет никаких оправданий. Так что вы можете «доверять», что в любом случае сломается.

<body>
 <div>
   <script>
     alert('<script> tags </script> are not '+
         'valid in regular old HTML without being escaped.');
   </script>
</body>

См.

http://jsbin.com/itevu

чтобы увидеть, как это сломалось. :)

2 голосов
/ 30 марта 2011

В некоторых случаях удаление тегов скрипта приводит к неверному HTML:

 <html>
    <head>
    </head>
    <body>
        <p>This should be
        <script type="text/javascript">
            document.writeln("<b");
        </script>>bolded</b>.
    </body>
 </html>
0 голосов
/ 06 февраля 2013

Возможно, вам пригодится альтернативный подход. Вы можете использовать следующую функцию для предотвращения запуска JavaScript:

function preventJS(html) {
   return html.replace(/<script(?=(\s|>))/i, '<script type="text/xml" ');
}

И он сохраняет теги script внутри DOM, поэтому сценарии можно использовать позже.

Я описал этот способ в своем блоге здесь - JavaScript: Как предотвратить выполнение JavaScript внутри HTML, добавляемого в DOM .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...