Добавить html в элемент jQuery без запуска скриптов внутри html
Я написал некоторый код, который берет строку html и очищает от него любой уродливый HTML, используя jQuery (см. ранний прототип в этот вопрос SO). Это работает очень хорошо, но я наткнулся на проблему:
При использовании .append(), чтобы обернуть html в div, все элементы script в коде оцениваются и запускаются (см. этот ответ SO для объяснение, почему это происходит). Я не хочу этого, я просто хочу, чтобы они были удалены, но я могу справиться с этим позже, если они не запущены.
Я использую этот код:
var wrapper = $('<div/>').append($(html));
Я попытался сделать это следующим образом:
var wrapper = $('<div>' + html + '</div>');
Но это просто приводит к ошибке "Access denied" в IE, которую исправляет функция append() (см. ответ, на который я ссылался выше).
Я думаю, что, возможно, мне удастся переписать мой код, чтобы не требовать обертку вокруг html, но я не уверен, и я хотел бы знать, можно ли добавлять html без запуска скриптов в нем.
Мои вопросы:
-
Как обернуть часть неизвестного html
без запуска скриптов внутри него,
предпочтительно удаляя их вообще?
-
Должен ли я выкинуть jQuery из окна
и сделайте это с помощью обычного JavaScript и
DOM-манипуляция вместо этого? Это поможет?
То, что я не пытаюсь сделать:
Я не пытаюсь поставить какой-то слой безопасности на стороне клиента. Я очень хорошо понимаю, что это было бы бессмысленно.
Обновление: предложение Джеймса
Джеймс предположил, что я должен отфильтровать элементы script, но посмотрите на эти два примера (первоначальное первое и предложение Джеймса):
jQuery("<p/>").append("<br/>hello<script type='text/javascript'>console.log('gnu!'); </script>there")
хранит текстовые узлы, но пишет gnu!
jQuery("<p/>").append(jQuery("<br/>hello<script type='text/javascript'>console.log('gnu!'); </script>there").not('script'))`
Не записывает gnu!, но также теряет текстовые узлы.
Обновление 2:
Джеймс обновил свой ответ, и я принял его. Однако см. Мой последний комментарий к его ответу.
Ответы
Ответ 1
Как насчет удаления скриптов в первую очередь?
var wrapper = $('<div/>').append($(html).not('script'));
Забастовкa >
- Создать контейнер div
- Используйте простой JS для размещения html в div
- Удалите все элементы script в div
Предполагая, что элементы script в html не вложены в другие элементы:
var wrapper = document.createElement('div');
wrapper.innerHTML = html;
$(wrapper).children().remove('script');
Забастовкa >
var wrapper = document.createElement('div');
wrapper.innerHTML = html;
$(wrapper).find('script').remove();
Это работает для случая, когда html является просто текстом и где html имеет текст вне любых элементов.
Ответ 2
Ниже приведен альтернативный способ предотвращения запуска скриптов из загруженного html:
function preventJS(html) {
return html.replace(/<script(?=(\s|>))/i, '<script type="text/xml" ');
}
Подробнее здесь описано JavaScript: как предотвратить выполнение JavaScript внутри html, добавляемого в DOM.
Вероятно, это решение будет полезно для кого-то.
Ответ 3
Вы должны удалить элементы script
:
var wrapper = $('<div/>').append($(html).remove("script"));
Забастовкa >
Вторая попытка:
node -validator может использоваться в браузере:
https://github.com/chriso/node-validator
var str = sanitize(large_input_str).xss();
В качестве альтернативы PHPJS имеет функцию strip_tags (regex/evil based):
http://phpjs.org/functions/strip_tags:535