私の問題
リッチ テキスト エディター (現時点では FCK 1.6) に貼り付けられた HTML をクリーンアップしたい。クリーニングは、タグのホワイトリスト (およびおそらく属性を持つ別のリスト) に基づいている必要があります。これは主に XSS を防ぐためではなく、見苦しい HTML を削除するためです。
現在、サーバー上でそれを行う方法は見当たらないので、JavaScript で行う必要があると思います。
現在のアイデア
jquery-clean プラグインを見つけましたが、私が見る限り、正規表現を使用して作業を行っており、安全ではないことがわかっています。
他の JS ベースのソリューションを見つけられなかったので、jQuery を使用して自分で実装し始めました。貼り付けた html ( ) の jQuery バージョンを作成し$(pastedHtml)
、結果のツリーをトラバースして、ホワイトリストに一致しない各要素を削除することで機能しますtagName
。
私の質問
- これはもっと良いですか?
- 貼り付けられたコンテンツを適切に表現するために jQuery を信頼できますか (一致しない終了タグと what-have-you がある可能性があります)。
- 私が見つけられなかったより良い解決策はすでにありますか?
アップデート
これは私の現在の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;
}
私はいくつかの点について疑問に思っています (コード内のコメントを参照してください)。
- jQuery の ":not" と一致させるために、ダミーの親で要素をラップする必要がありますか?
- これは、新しいノードを作成するための推奨される方法ですか?