htmlyer
Version:
135 lines (101 loc) • 2.92 kB
text/typescript
const spCharCodes = '[\\u0000-\\u001F]|\\u00F1|\\u000B|\\u000C|\\u00A0|\\uFEFF|\\u1680|\\u180E|[\\u2000-\\u200F]|\\u2028|\\u2029|\\u202F|\\u205F|\\u3000';
function getStrValue(str: any): string {
if (str === null || str === undefined || typeof str == 'function') {
str = '';
} else {
str += '';
}
return str;
}
type EscapeMap = {
[word: string]: string
};
const HtmlEscapeMap: EscapeMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'`': '`',
'\\': '\',
};
function escapeMap2RegExpStr(escapeMap: EscapeMap) {
return Object.keys(escapeMap)
.map(v => ({
'\\': '\\\\',
'\n': '\\n',
'\r': '\\r',
}[v] || v))
.join('|');
}
export const htmlEncode = (function() {
const escapeMap = {
...HtmlEscapeMap,
};
const reg = new RegExp(escapeMap2RegExpStr(escapeMap), 'g');
function rp(all: string) {
return escapeMap[all] || '';
}
return function(str: any): string {
str = getStrValue(str);
if (!str) return str;
return str.replace(reg, rp);
};
})();
export const jsEncode = (function () {
// 可以再添加一个\/ 主要是防止// 或则/**/这些组合注释 (有一个地方没有encode,可能会导致一片代码被波及)
const escapeMap: EscapeMap = {
'\n': '\\n',
'\r': '\\r',
'\\': '\\\\',
'/': '\\/',
'"': '\\"',
"'": "\\'",
'>': '\\>',
// 增加> | < 防止在script标签中,中xss
'<': '\\u003c',
'`': '\\`',
};
const reg = new RegExp(escapeMap2RegExpStr(escapeMap) + '|' + spCharCodes, 'g');
function rp(str: string) {
return escapeMap[str] || '\\u' + str.charCodeAt(0).toString(16).padStart(4, '0');
}
return function(str: any): string {
str = getStrValue(str);
if (!str) return str;
return str.replace(reg, rp);
};
})();
export function urlEncode(str: any): string {
str = getStrValue(str);
if (!str) return str;
return encodeURIComponent(str);
}
export const jsonStringify = (function() {
const scriptTagReg = /</g;
return function(data: any, replacer?: any, space?: string): string {
const result = JSON.stringify(data, replacer, space);
if (!result) return '';
// 防</script> xss
// 由于stringify本身就会对里面的数据进行一些encode
// 而且都是jsEncode类型,所以不担心htmlEncode分支
return result.replace(scriptTagReg, '\\u003c');
};
})();
export const input2html = (function() {
const escapeMap: EscapeMap = {
...HtmlEscapeMap,
' ': ' ',
'\n': '<br/>',
'\r': '',
};
const reg = new RegExp(escapeMap2RegExpStr(escapeMap) + '|' + spCharCodes, 'g');
function rp(all: string) {
return escapeMap[all] || '&#' + all.charCodeAt(0) + ';';
}
return function(str: any): string {
str = getStrValue(str);
if (!str) return str;
return str.replace(reg, rp);
};
})();