我需要使用JavaScript验证web应用程序中的HTML用户输入。
到目前为止,我所做的基于这个question:我使用第三方库sanitize-html,对输入进行清理,然后将其与原始库进行比较。如果它们不同,则Html无效。

const isValidHtml = (html: string): boolean => {
    let sanitized = sanitizeHtml(html, sanitizationConfig);
    sanitized = sanitized.replace(/\s/g, '').replace(/<br>|<br\/>/g, ''); // different browser's behavior for <br>
    html = html.replace(/\s/g, '').replace(/<br>|<br\/>/g, '');
    return sanitized === html;
}

上面的方法可以很好地处理未转义的Html,但不能处理转义的Html。
isValidHtml('<'); // false
isValidHtml('&lt;'); // true
isValidHtml('<script>'); // false
isValidHtml('&lt;script&gt;'); // true, this should be false also!!!

我用这种方法漏掉了什么吗?
有没有更好的方法来完成这项任务?
编辑:
正如@brad在评论中所建议的,我首先尝试解码Html:
decodeHtml(html: string): string {
    const txt = document.createElement('textarea');
    txt.innerHTML = html;
    const decodedHtml = txt.value;
    txt.textContent = null;
    return decodedHtml;
}

然后打电话给isValid(decodedHtml),我得到了这个结果:
isValidHtml('<'); // false
isValidHtml('&lt;'); // false, this should be true!!!
isValidHtml('<script>'); // false
isValidHtml('&lt;script&gt;'); // false

最佳答案

如果您实际上并没有试图验证HTML,而只是试图确保它最终是有效的,那么我建议您通过DOM解析器运行它并将HTML返回,从而有效地让浏览器为您完成工作。
未经测试,但像这样:

const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
console.log(doc.documentElement.innerHTML);

基本上,您可以使用浏览器的内置解析来处理任何错误,不管怎样,它都是以标准的方式处理的。它将创建一个节点树。从节点树中,生成保证有效的HTML。
另请参见:https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Parsing_an_SVG_or_HTML_document

10-05 20:40
查看更多