为什么要转义?
转义可以防止 xss 攻击。接下来,我们来看一下如何转义。
HTML Sanitizer API
Sanitizer 是浏览器自带的转义方法,在2021年初被提出,兼容性问题很大。
列举几个常用的 API:
const $div = document.querySelector('div');
const user_input = `<em>Hello There</em><img src="" onerror=alert(0)>`;
const sanitizer = new Sanitizer()
$div.setHTML(user_input, sanitizer); // <div><em>Hello There</em><img src=""></div>
const user_input = `<em>Hello There</em><img src="" onerror=alert(0)>`
const sanitizer = new Sanitizer()
sanitizer.sanitizeFor("div", user_input) // HTMLDivElement <div>
sanitizer.sanitizeFor("div", user_input).innerHTML // <em>Hello There</em><img src="">
自定义方法进行转义
这是一个简单的转义,只会把跟 html 有冲突的标签进行转义。
const escapeMap = {
//'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
function escape(string = '') {
const reg = new RegExp(`[${Object.keys(escapeMap).join('')}]`, 'g');
return string.replace(reg, item => escapeMap[item]);
}
防止用户输入恶意篡改,Vue,JSX 默认情况下不用处理,插入的文本都是按照字符串处理。Vue中用 v-html 引入的内容要做转义。
第三方库转义
DOMPurify
转义库里面 GitHub star 最多,11.5k。
const user_input = '<em>Hello There</em><img src="" onerror=alert(0)>';
const cleanedHtml = DOMPurify.sanitize(user_input); // <em>Hello There</em><img src="">
还可以根据需要定义自己的白名单(允许的标签)和属性,比如字符串中包含自定义标签和属性时就需要用到。