用于转义 html 标签的 Joi 扩展
Joi extension for escaping html tags
我想创建扩展程序来清理字符串输入并剥离 html 标签。
为此,我使用 sanitize-html npm 包。
这是我目前尝试过的方法。
const sanitizeHtml = require('sanitize-html');
module.exports = function htmlStrip(joi) {
return {
type: 'htmlStrip',
base: joi.string(),
messages: {
htmlStrip: 'Should not contain any html tags.',
},
validate(value, helpers) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean) {
return clean;
}
return { value, errors: helpers.error('htmlStrip') };
},
};
};
但是我遇到了以下错误。
TypeError: Joi.string(...).trim(...).htmlStrip is not a function
我也试过如下传递规则对象,但仍然出现同样的错误。
const sanitizeHtml = require('sanitize-html');
module.exports = function htmlStrip(joi) {
return {
type: 'htmlStrip',
base: joi.string(),
messages: {
htmlStrip: 'Should not contain any html tags.',
},
rules: {
htmlStrip: {
validate(params, value, state, options) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean) {
return clean;
}
return this.createError('string.htmlStrip', { value }, state, options);
},
},
},
};
};
我正在关注提到的文档 here。
这就是我使用扩展验证器的方式。
const Joi = require('@hapi/joi').extend(require('@hapi/joi-date')).extend(require('../utils/sanitize-html-joi'));
const validateAddressCreateData = (data) => {
const schema = Joi.object({
address: Joi.string().trim().htmlStrip().required(),
label: Joi.string()
.required(),
});
return schema.validate(data);
};
不确定为什么你假设 Joi.string().trim()
的类型将与 Joi
相同,考虑到你扩展了 Joi
对象,但期望 htmlStrip
是Joi.string().trim()
个结果可用。
两种类型的简单 console.log 表明它们是不同的类型。
console.log(Object.keys(Joi))
:
[ '_types',
'alternatives',
'any',
'array',
'boolean',
...
'htmlStrip' ]
console.log(Object.keys(Joi.string().trim());
:
[ 'type',
'$_root',
'$_temp',
'_ids',
'_preferences',
'_valids',
'_invalids',
'_rules',
'_singleRules',
'_refs',
'_flags',
'_cache',
'$_terms',
'$_super' ]
trim
的结果 $_super
似乎不包含任何键,因此它们并不真正相关。
我相信如果你想pre-process你的输入然后然后使用你的htmlStrip
,你必须做这样的事情:
const sanitizeHtml = require('sanitize-html');
module.exports = function htmlStrip(joi) {
return {
type: 'htmlStrip',
base: joi.string(),
messages: {
htmlStrip: 'Should not contain any html tags.',
},
validate(value, helpers) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean == value) {
return { clean, errors: [] };
}
return { value, errors: helpers.error('htmlStrip') };
},
};
};
以下是我的使用方法:
const Joi = require('@hapi/joi').extend(require('@hapi/joi-date')).extend(require('./san'));
const validateAddressCreateData = (data) => {
const schema = Joi.object({
address: Joi.htmlStrip(Joi.string().trim()).required(),
label: Joi.string().required(),
});
return schema.validate(data);
};
console.log(validateAddressCreateData({ address: "<body>test</body>", label: "abc"}));
但我不确定输出是否如您预期的那样:
{ value: { address: '<body>test</body>', label: 'abc' },
error:
{ ValidationError: Should not contain any html tags.
_original: { address: '<body>test</body>', label: 'abc' },
details: [ [Object] ] } }
所以,它似乎根据定义的验证消息来验证输入。或者您真的想 修改 正在传递的地址 html 吗?
编辑 现在明白您的意思了,相应地修改了 htmlStrip
。请看比较if(value == clean)
。如果消毒剂不需要 trim 任何东西,则意味着输入字符串不包含任何 html 标签。 Return 其他情况错误。
使用自定义验证导出 Joi 将解决此问题(custom_joi.js)
const sanitizeHtml = require('sanitize-html');
const Joi = require('@hapi/joi')
module.exports = Joi.extend((joi) => ({
type: "string",
base: joi.string(),
messages: {
"string.htmlStrip": "{{#label}} not contain any html tags"
},
rules: {
htmlStrip: {
validate(value, helpers) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean == value) {
return clean;
}
return helpers.error("string.htmlStrip")
}
} } } ) )
并在控制器中导入我们的自定义文件
const Joi = require('../../_helpers/custom_joi');
然后创建验证架构
const schema = Joi.object().keys({
notes: Joi.string().htmlStrip().allow('', null),
specialInstructions: Joi.string().htmlStrip()
});
const { error, value } = schema.validate(req.body);
我想创建扩展程序来清理字符串输入并剥离 html 标签。
为此,我使用 sanitize-html npm 包。
这是我目前尝试过的方法。
const sanitizeHtml = require('sanitize-html');
module.exports = function htmlStrip(joi) {
return {
type: 'htmlStrip',
base: joi.string(),
messages: {
htmlStrip: 'Should not contain any html tags.',
},
validate(value, helpers) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean) {
return clean;
}
return { value, errors: helpers.error('htmlStrip') };
},
};
};
但是我遇到了以下错误。
TypeError: Joi.string(...).trim(...).htmlStrip is not a function
我也试过如下传递规则对象,但仍然出现同样的错误。
const sanitizeHtml = require('sanitize-html');
module.exports = function htmlStrip(joi) {
return {
type: 'htmlStrip',
base: joi.string(),
messages: {
htmlStrip: 'Should not contain any html tags.',
},
rules: {
htmlStrip: {
validate(params, value, state, options) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean) {
return clean;
}
return this.createError('string.htmlStrip', { value }, state, options);
},
},
},
};
};
我正在关注提到的文档 here。
这就是我使用扩展验证器的方式。
const Joi = require('@hapi/joi').extend(require('@hapi/joi-date')).extend(require('../utils/sanitize-html-joi'));
const validateAddressCreateData = (data) => {
const schema = Joi.object({
address: Joi.string().trim().htmlStrip().required(),
label: Joi.string()
.required(),
});
return schema.validate(data);
};
不确定为什么你假设 Joi.string().trim()
的类型将与 Joi
相同,考虑到你扩展了 Joi
对象,但期望 htmlStrip
是Joi.string().trim()
个结果可用。
两种类型的简单 console.log 表明它们是不同的类型。
console.log(Object.keys(Joi))
:
[ '_types',
'alternatives',
'any',
'array',
'boolean',
...
'htmlStrip' ]
console.log(Object.keys(Joi.string().trim());
:
[ 'type',
'$_root',
'$_temp',
'_ids',
'_preferences',
'_valids',
'_invalids',
'_rules',
'_singleRules',
'_refs',
'_flags',
'_cache',
'$_terms',
'$_super' ]
trim
的结果 $_super
似乎不包含任何键,因此它们并不真正相关。
我相信如果你想pre-process你的输入然后然后使用你的htmlStrip
,你必须做这样的事情:
const sanitizeHtml = require('sanitize-html');
module.exports = function htmlStrip(joi) {
return {
type: 'htmlStrip',
base: joi.string(),
messages: {
htmlStrip: 'Should not contain any html tags.',
},
validate(value, helpers) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean == value) {
return { clean, errors: [] };
}
return { value, errors: helpers.error('htmlStrip') };
},
};
};
以下是我的使用方法:
const Joi = require('@hapi/joi').extend(require('@hapi/joi-date')).extend(require('./san'));
const validateAddressCreateData = (data) => {
const schema = Joi.object({
address: Joi.htmlStrip(Joi.string().trim()).required(),
label: Joi.string().required(),
});
return schema.validate(data);
};
console.log(validateAddressCreateData({ address: "<body>test</body>", label: "abc"}));
但我不确定输出是否如您预期的那样:
{ value: { address: '<body>test</body>', label: 'abc' },
error:
{ ValidationError: Should not contain any html tags.
_original: { address: '<body>test</body>', label: 'abc' },
details: [ [Object] ] } }
所以,它似乎根据定义的验证消息来验证输入。或者您真的想 修改 正在传递的地址 html 吗?
编辑 现在明白您的意思了,相应地修改了 htmlStrip
。请看比较if(value == clean)
。如果消毒剂不需要 trim 任何东西,则意味着输入字符串不包含任何 html 标签。 Return 其他情况错误。
使用自定义验证导出 Joi 将解决此问题(custom_joi.js)
const sanitizeHtml = require('sanitize-html');
const Joi = require('@hapi/joi')
module.exports = Joi.extend((joi) => ({
type: "string",
base: joi.string(),
messages: {
"string.htmlStrip": "{{#label}} not contain any html tags"
},
rules: {
htmlStrip: {
validate(value, helpers) {
const clean = sanitizeHtml(value, {
allowedTags: [],
allowedAttributes: {},
});
if (clean == value) {
return clean;
}
return helpers.error("string.htmlStrip")
}
} } } ) )
并在控制器中导入我们的自定义文件
const Joi = require('../../_helpers/custom_joi');
然后创建验证架构
const schema = Joi.object().keys({
notes: Joi.string().htmlStrip().allow('', null),
specialInstructions: Joi.string().htmlStrip()
});
const { error, value } = schema.validate(req.body);