[英]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 不是函數
我也嘗試過如下傳遞規則對象,但仍然遇到相同的錯誤。
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);
},
},
},
};
};
我正在關注這里提到的文檔。
這就是我使用擴展驗證器的方式。
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
似乎不包含任何鍵,因此它們並沒有真正相關。
我相信如果你想預處理你的輸入然后使用你的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)
。 如果消毒劑不需要修剪任何東西,這意味着輸入字符串不包含任何 html 標簽。 其他情況下返回錯誤。
使用自定義驗證導出 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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.