Разумно ли использовать jQuery для тегов белого списка? Существуют ли решения в JavaScript? - PullRequest
3 голосов
/ 17 марта 2011

Моя проблема

Я хочу очистить 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;
}

Мне интересно узнать о некоторых моментах (см. комментарии в коде);

  1. Нужно ли мне оборачивать свой элемент в фиктивного родителя, чтобы иметь возможностьчтобы сопоставить его с ": not" в jQuery?
  2. Это рекомендуемый способ создания нового узла?

1 Ответ

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

Если вы используете возможности HTML-коррекции браузера (например, копируете форматированный текст в innerHTML пустого div и берете получившееся дерево DOM), HTML-код гарантированно будет действительным (так, как он будетбыть исправлено несколько зависит от браузера).Хотя это, вероятно, в любом случае возможно с помощью богатого редактора.

Преобразование DOM с собственным текстом в jQuery, вероятно, также безопасно, но определенно медленнее, поэтому я бы его избегал.

Использование белого списка на основеСелекторный механизм jQuery может быть несколько хитрым, потому что удаление элемента при сохранении его дочерних элементов может сделать документ недействительным, поэтому браузер исправит его, изменив дерево DOM, что может запутать скрипт, пытающийся перебрать недопустимые элементы.(Например, вы разрешаете ul и li, но не ol; скрипт удаляет корневой элемент списка, голые li элементы недопустимы, поэтому браузер снова оборачивает их в ul, что ul будет пропущенопо сценарию очистки.) Если вы выбрасываете нежелательные элементы вместе со всеми их дочерними элементами, я не вижу никаких проблем с этим.

...