207 lines
5.6 KiB
JavaScript
207 lines
5.6 KiB
JavaScript
/**
|
||
* 路径匹配器
|
||
* @param {string} pattern
|
||
* @param {string} path
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isPathMatch(pattern, path) {
|
||
const regexPattern = pattern
|
||
.replace(/\//g, '\\/')
|
||
.replace(/\*\*/g, '.*')
|
||
.replace(/\*/g, '[^\\/]*')
|
||
const regex = new RegExp(`^${regexPattern}$`)
|
||
return regex.test(path)
|
||
}
|
||
|
||
/**
|
||
* 判断value字符串是否为空
|
||
* @param {string} value
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isEmpty(value) {
|
||
if (
|
||
value == null ||
|
||
value == '' ||
|
||
value == undefined ||
|
||
value == 'undefined'
|
||
) {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
/**
|
||
* 判断url是否是http或https
|
||
* @param {string} url
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isHttp(url) {
|
||
return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
|
||
}
|
||
|
||
/**
|
||
* 判断path是否为外链
|
||
* @param {string} path
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isExternal(path) {
|
||
return /^(https?:|mailto:|tel:)/.test(path)
|
||
}
|
||
|
||
/**
|
||
* @param {string} str
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validUsername(str) {
|
||
const valid_map = ['admin', 'editor']
|
||
return valid_map.indexOf(str.trim()) >= 0
|
||
}
|
||
|
||
/**
|
||
* @param {string} url
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validURL(url) {
|
||
const reg =
|
||
/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
|
||
return reg.test(url)
|
||
}
|
||
|
||
/**
|
||
* @param {string} str
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validLowerCase(str) {
|
||
const reg = /^[a-z]+$/
|
||
return reg.test(str)
|
||
}
|
||
|
||
/**
|
||
* @param {string} str
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validUpperCase(str) {
|
||
const reg = /^[A-Z]+$/
|
||
return reg.test(str)
|
||
}
|
||
|
||
/**
|
||
* @param {string} str
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validAlphabets(str) {
|
||
const reg = /^[A-Za-z]+$/
|
||
return reg.test(str)
|
||
}
|
||
|
||
/**
|
||
* @param {string} email
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validEmail(email) {
|
||
const reg =
|
||
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||
return reg.test(email)
|
||
}
|
||
|
||
/**
|
||
* 中国大陆手机号校验
|
||
* 规则:可选国家码(+86/0086/86),以 1 开头的 11 位号码,号段 1[3-9]
|
||
* @param {string|number} mobile
|
||
* @returns {Boolean}
|
||
*/
|
||
export function validMobile(mobile) {
|
||
const value = String(mobile || '').trim()
|
||
const reg = /^(?:(?:\+|00)?86)?1[3-9]\d{9}$/
|
||
return reg.test(value)
|
||
}
|
||
/* 身份证号校验 */
|
||
export function validIdCard(idCard) {
|
||
const value = String(idCard || '').trim()
|
||
// 基础格式:15位或18位,最后一位可以是数字或X
|
||
const reg = /(^\d{15}$)|(^\d{17}(\d|X|x)$)/
|
||
return reg.test(value)
|
||
}
|
||
|
||
/**
|
||
* @param {string} str
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isString(str) {
|
||
return typeof str === 'string' || str instanceof String
|
||
}
|
||
|
||
/**
|
||
* @param {Array} arg
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isArray(arg) {
|
||
if (typeof Array.isArray === 'undefined') {
|
||
return Object.prototype.toString.call(arg) === '[object Array]'
|
||
}
|
||
return Array.isArray(arg)
|
||
}
|
||
|
||
/**
|
||
* 判断是否为合法的 IPv4 地址
|
||
* @param {string} ip
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isIPv4(ip) {
|
||
if (typeof ip !== 'string') return false
|
||
// 基础格式校验:四段数字
|
||
const parts = ip.split('.')
|
||
if (parts.length !== 4) return false
|
||
for (let i = 0; i < parts.length; i++) {
|
||
const seg = parts[i]
|
||
// 不能为空,必须为数字,不能有前导零(允许单个0)
|
||
if (seg === '' || /\D/.test(seg)) return false
|
||
if (seg.length > 1 && seg[0] === '0') return false
|
||
const n = Number(seg)
|
||
if (n < 0 || n > 255) return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
/**
|
||
* 将 IPv4 地址转换为 32 位整数(仅内部使用,入参须先通过 isIPv4)
|
||
* @param {string} ip
|
||
* @returns {number}
|
||
*/
|
||
function ipv4ToInt(ip) {
|
||
const [a, b, c, d] = ip.split('.').map(Number)
|
||
return ((a << 24) >>> 0) + (b << 16) + (c << 8) + d
|
||
}
|
||
|
||
/**
|
||
* 判断起始 IP 是否小于等于结束 IP(均为 IPv4)
|
||
* @param {string} start
|
||
* @param {string} end
|
||
* @returns {Boolean}
|
||
*/
|
||
export function isIPv4RangeOrder(start, end) {
|
||
if (!isIPv4(start) || !isIPv4(end)) return false
|
||
return ipv4ToInt(start) <= ipv4ToInt(end)
|
||
}
|
||
|
||
/**
|
||
* 统一安全校验方法
|
||
* 使用方法:validSecurity(str) 返回 true/false
|
||
*/
|
||
|
||
/**
|
||
* 统一安全校验方法
|
||
* 使用方法:validSecurity(str) 返回 true/false
|
||
*/
|
||
|
||
export function validSecurity(str) {
|
||
if (!str || typeof str !== 'string') {
|
||
return true;
|
||
}
|
||
|
||
// 将所有正则模式合并为一个统一的正则表达式
|
||
const securityRegex = /<script>(.*?)<\/script>|src[\r\n]*=[\r\n]*'(.*?)'|src[\r\n]*=[\r\n]*"(.*?)"|<\/script>|<script(.*?)>|eval\((.*?)\)|e-xpression\((.*?)\)|javascript:|vbscript:|onload(.*?)=|onerror(.*?)=|onclick(.*?)=|onmouseover(.*?)=|alert\((.*?)\)|<.*>|\[.*\]|\(.*\)|'.*'|".*"|%3c|%3e|%2f|%27|%22|%2b|%3b|%28|%29|%5b|%5d|@.*|!.*|%.*|\\x3c|\\x3e|\\x2f|\\x27|\\x22|data:text\/html|base64|document\.|window\.|location\.|cookie|--|\/\*.*?\*\/|#|'|"|\bselect\b|\binsert\b|\bupdate\b|\bdelete\b|\bdrop\b|\btruncate\b|\balter\b|\bcreate\b|\bexec\b|\bexecute\b|\bdeclare\b|\bxp_cmdshell\b|\bsp_\w+\b|\bchar\b|\bascii\b|\bsubstr\b|\bsubstring\b|\bconcat\b|\bmaster\b|\bsys\b|\binformation_schema\b|\bunion\b|\binto\b|\bfrom\b|\bwhere\b|\band\b|\bor\b/i;
|
||
|
||
return !securityRegex.test(str);
|
||
}
|