Моя проблема
Я хочу очистить HTML, вставленный в текстовый редактор (на данный момент FCK 1.6).Очистка должна основываться на белом списке тегов (и, возможно, другом с атрибутами).Это в первую очередь не для предотвращения XSS, а для удаления некрасивого HTML.
В настоящее время я не вижу способа сделать это на сервере, поэтому я предполагаю, что это должно быть сделано в JavaScript.
Текущие идеи
Я нашел jquery-clean плагин , но, насколько я понимаю, он использует регулярные выражения для выполнения работы, и мы знаем, что это небезопасно .
Поскольку я не нашел другого решения на основе JS, я сам начал использовать его с помощью jQuery.Это сработало бы, создав jQuery-версию вставленного html ($(pastedHtml)
), а затем проследив итоговое дерево, удалив каждый элемент, не соответствующий белому списку, просмотрев атрибут tagName
.
Мои вопросы
- Это лучше?
- Могу ли я доверять jQuery для хорошего представления вставленного контента (могут быть непревзойденные конечные теги и что-у вас)?
- Есть ли уже лучшее решение, которое я не смог найти?
Обновление
Это мое текущее решение на основе jQuery (подробное и не очень)проверено):
function clean(element, whitelist, replacerTagName) {
// Use div if no replace tag was specified
replacerTagName = replacerTagName || "div";
// Accept anything that jQuery accepts
var jq = $(element);
// Create a a copy of the current element, but without its children
var clone = jq.clone();
clone.children().remove();
// Wrap the copy in a dummy parent to be able to search with jQuery selectors
// 1)
var wrapper = $('<div/>').append(clone);
// Check if the element is not on the whitelist by searching with the 'not' selector
var invalidElement = wrapper.find(':not(' + whitelist + ')');
// If the element wasn't on the whitelist, replace it.
if (invalidElement.length > 0) {
var el = $('<' + replacerTagName + '/>');
el.text(invalidElement.text());
invalidElement.replaceWith(el);
}
// Extract the (maybe replaced) element
var cleanElement = $(wrapper.children().first());
// Recursively clean the children of the original element and
// append them to the cleaned element
var children = jq.children();
if (children.length > 0) {
children.each(function(_index, thechild) {
var cleaned = clean(thechild, whitelist, replacerTagName);
cleanElement.append(cleaned);
});
}
return cleanElement;
}
Мне интересно узнать о некоторых моментах (см. комментарии в коде);
- Нужно ли мне оборачивать свой элемент в фиктивного родителя, чтобы иметь возможностьчтобы сопоставить его с ": not" в jQuery?
- Это рекомендуемый способ создания нового узла?