字段校验规则清单:必填/范围/唯一/组合唯一/正则(附校验表)

前言

字段校验是防止脏数据的第一道防线。很多线上问题都是因为校验不全:没有校验长度、没有校验格式、没有校验唯一性。这篇给你完整的校验规则清单+校验表模板。使用

一、6类校验规则

校验类型 说明 示例 错误提示
必填 字段不能为空 用户名必填 请输入用户名
长度 字符串长度限制 3-20个字符 用户名长度为3-20个字符
范围 数值范围限制 0-100 数值必须在0-100之间
唯一 字段值不能重复 手机号唯一 该手机号已存在
组合唯一 多个字段组合不能重复 商品+规格唯一 该规格组合已存在
正则 格式校验 邮箱格式 邮箱格式不正确

二、校验规则模板

必填校验

复制代码
字段名:用户名
是否必填:是
前端校验:提交时检查,为空则提示
后端校验:参数校验,为空返回400
错误提示:请输入用户名

长度校验

复制代码
字段名:用户名
长度限制:3-20个字符
前端校验:输入时实时提示
后端校验:参数校验,超长返回400
错误提示:用户名长度为3-20个字符

范围校验

复制代码
字段名:年龄
范围限制:≥0 且 ≤150
前端校验:输入时检查
后端校验:参数校验,超范围返回400
错误提示:年龄必须在0-150之间

唯一性校验

复制代码
字段名:手机号
唯一性要求:全局唯一
前端校验:失焦时调用接口检查
后端校验:数据库唯一索引
错误提示:该手机号已注册

组合唯一性校验

复制代码
字段名:商品SKU
组合唯一:商品ID + 颜色 + 尺码
前端校验:选择规格时检查
后端校验:数据库联合唯一索引
错误提示:该规格组合已存在

正则校验

复制代码
字段名:邮箱
正则表达式:^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
前端校验:失焦时检查
后端校验:参数校验
错误提示:邮箱格式不正确

字段名:手机号
正则表达式:^1[3-9]\d{9}$
错误提示:手机号格式不正确

字段名:身份证号
正则表达式:^\d{17}[\dXx]$
错误提示:身份证号格式不正确

三、校验表模板

字段名 必填 长度 范围 唯一 正则 错误提示
用户名 3-20 - ^[a-zA-Z0-9_]+$ 用户名已存在
密码 6-20 - - 密码长度为6-20个字符
手机号 11 - ^1[3-9]\d{9}$ 手机号已注册
年龄 - 0-150 - 年龄必须在0-150之间

四、校验实现步骤

步骤1:前端校验

在表单提交前进行前端校验,提供即时反馈。

复制代码
前端校验示例(JavaScript):
// 必填校验
function validateRequired(value, fieldName) {
    if (!value || value.trim() === '') {
        return `${fieldName}不能为空`;
    }
    return null;
}

// 长度校验
function validateLength(value, min, max, fieldName) {
    if (value.length < min || value.length > max) {
        return `${fieldName}长度为${min}-${max}个字符`;
    }
    return null;
}

// 范围校验
function validateRange(value, min, max, fieldName) {
    const num = Number(value);
    if (isNaN(num) || num < min || num > max) {
        return `${fieldName}必须在${min}-${max}之间`;
    }
    return null;
}

// 正则校验
function validateRegex(value, regex, fieldName, errorMsg) {
    if (!regex.test(value)) {
        return errorMsg || `${fieldName}格式不正确`;
    }
    return null;
}

// 唯一性校验(异步)
async function validateUnique(value, apiUrl, fieldName) {
    const response = await fetch(`${apiUrl}?value=${value}`);
    const data = await response.json();
    if (data.exists) {
        return `${fieldName}已存在`;
    }
    return null;
}

步骤2:后端校验

在接口层进行后端校验,确保数据安全。

复制代码
后端校验示例(Node.js Express):
const { body, validationResult } = require('express-validator');

// 校验规则
const validateUser = [
    body('username')
        .notEmpty().withMessage('用户名不能为空')
        .isLength({ min: 3, max: 20 }).withMessage('用户名长度为3-20个字符')
        .matches(/^[a-zA-Z0-9_]+$/).withMessage('用户名只能包含字母、数字、下划线'),
    
    body('phone')
        .notEmpty().withMessage('手机号不能为空')
        .matches(/^1[3-9]\d{9}$/).withMessage('手机号格式不正确')
        .custom(async (value) => {
            const exists = await checkPhoneExists(value);
            if (exists) {
                throw new Error('手机号已注册');
            }
        }),
    
    body('age')
        .optional()
        .isInt({ min: 0, max: 150 }).withMessage('年龄必须在0-150之间'),
    
    (req, res, next) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({
                code: 400,
                message: '参数校验失败',
                errors: errors.array()
            });
        }
        next();
    }
];

// 使用
app.post('/api/users', validateUser, createUser);

步骤3:数据库约束

在数据库层添加约束,作为最后一道防线。

复制代码
数据库约束示例(MySQL):
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20) NOT NULL COMMENT '用户名',
    phone VARCHAR(11) NOT NULL COMMENT '手机号',
    email VARCHAR(100) COMMENT '邮箱',
    age INT COMMENT '年龄',
    
    -- 唯一性约束
    UNIQUE KEY uk_username (username),
    UNIQUE KEY uk_phone (phone),
    
    -- 检查约束(MySQL 8.0+)
    CHECK (LENGTH(username) >= 3 AND LENGTH(username) <= 20),
    CHECK (phone REGEXP '^1[3-9][0-9]{9}$'),
    CHECK (age IS NULL OR (age >= 0 AND age <= 150))
) COMMENT='用户表';

五、常用正则表达式

基础正则表达式

复制代码
手机号:^1[3-9]\d{9}$
邮箱:^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
身份证:^\d{17}[\dXx]$
URL:^https?://[^\s]+$
IP地址:^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$
日期(YYYY-MM-DD):^\d{4}-\d{2}-\d{2}$
中文:^[\u4e00-\u9fa5]+$
数字:^\d+$
字母:^[a-zA-Z]+$
字母数字:^[a-zA-Z0-9]+$

复杂正则表达式

复制代码
银行卡号:^\d{16,19}$(16-19位数字)
密码(6-20位,包含字母和数字):^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z0-9]{6,20}$
密码(6-20位,包含大小写字母、数字、特殊字符):
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{6,20}$
时间(HH:mm:ss):^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
日期时间(YYYY-MM-DD HH:mm:ss):
^\d{4}-\d{2}-\d{2} ([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$
金额(最多2位小数):^\d+(\.\d{1,2})?$
百分比(0-100,最多2位小数):^(100(\.0{1,2})?|([0-9]|[1-9][0-9])(\.\d{1,2})?)$

六、实际案例

案例1:用户注册校验

**业务场景:**用户注册时需要校验用户名、手机号、密码等字段。

复制代码
校验规则:

| 字段名 | 必填 | 长度 | 范围 | 唯一 | 正则 | 错误提示 |
|--------|------|------|------|------|------|---------|
| 用户名 | 是 | 3-20 | - | 是 | ^[a-zA-Z0-9_]+$ | 用户名已存在 |
| 密码 | 是 | 6-20 | - | 否 | ^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z0-9]{6,20}$ | 密码必须包含字母和数字 |
| 手机号 | 是 | 11 | - | 是 | ^1[3-9]\d{9}$ | 手机号已注册 |
| 邮箱 | 否 | - | - | 是 | ^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$ | 邮箱格式不正确 |
| 年龄 | 否 | - | 0-150 | 否 | - | 年龄必须在0-150之间 |

校验顺序:
1. 前端校验:提交时检查必填、长度、格式
2. 后端校验:接口层校验所有规则
3. 数据库约束:唯一性约束、检查约束

案例2:商品信息校验

**业务场景:**商品创建时需要校验商品名称、价格、库存等字段。

复制代码
校验规则:

| 字段名 | 必填 | 长度 | 范围 | 唯一 | 正则 | 错误提示 |
|--------|------|------|------|------|------|---------|
| 商品名称 | 是 | 1-100 | - | 否 | - | 商品名称不能为空 |
| 商品价格 | 是 | - | ≥0.01, ≤999999.99 | 否 | ^\d+(\.\d{1,2})?$ | 价格必须在0.01-999999.99之间 |
| 库存数量 | 是 | - | ≥0, ≤999999 | 否 | ^\d+$ | 库存数量必须在0-999999之间 |
| 商品SKU | 是 | - | - | 组合唯一(商品ID+颜色+尺码) | - | 该规格组合已存在 |
| 商品图片 | 是 | - | - | 否 | - | 商品图片不能为空 |

组合唯一校验:
- 商品ID + 颜色 + 尺码:组合唯一
- 数据库:UNIQUE KEY uk_sku (product_id, color, size)

案例3:订单信息校验

**业务场景:**订单创建时需要校验订单金额、收货地址等字段。

复制代码
校验规则:

| 字段名 | 必填 | 长度 | 范围 | 唯一 | 正则 | 错误提示 |
|--------|------|------|------|------|------|---------|
| 订单金额 | 是 | - | ≥0.01 | 否 | ^\d+(\.\d{1,2})?$ | 订单金额不能为空 |
| 收货人 | 是 | 1-50 | - | 否 | - | 收货人不能为空 |
| 收货手机 | 是 | 11 | - | 否 | ^1[3-9]\d{9}$ | 手机号格式不正确 |
| 收货地址 | 是 | 1-200 | - | 否 | - | 收货地址不能为空 |
| 备注 | 否 | ≤500 | - | 否 | - | 备注不能超过500个字符 |

业务校验:
- 订单金额 = 商品总价(需要后端校验)
- 库存是否充足(需要后端校验)

七、常见错误

错误1:只做前端校验

**问题:**只在前端校验,后端不校验,用户可以直接调用接口绕过。

复制代码
❌ 错误示例:
前端:校验用户名长度3-20
后端:不校验,直接保存

问题:用户可以直接调用接口,传入1个字符的用户名。

✅ 正确示例:
前端:校验用户名长度3-20(用户体验优化)
后端:校验用户名长度3-20(安全控制)
数据库:CHECK约束(最后一道防线)

错误2:唯一性校验不完整

**问题:**只在前端或后端校验唯一性,没有数据库唯一索引。

复制代码
❌ 错误示例:
前端:失焦时调用接口检查唯一性
后端:查询数据库检查唯一性
数据库:没有唯一索引

问题:并发情况下,可能插入重复数据。

✅ 正确示例:
前端:失焦时调用接口检查(用户体验优化)
后端:查询数据库检查(业务校验)
数据库:唯一索引(最后一道防线)

CREATE TABLE users (
    username VARCHAR(20) NOT NULL,
    UNIQUE KEY uk_username (username)  -- 唯一索引
);

错误3:校验规则不一致

**问题:**前端和后端的校验规则不一致,导致用户体验差。

复制代码
❌ 错误示例:
前端:用户名长度3-20
后端:用户名长度5-20

问题:前端校验通过,后端校验失败,用户体验差。

✅ 正确示例:
前端和后端使用相同的校验规则:
- 使用配置文件统一管理校验规则
- 前端和后端共享配置
- 校验规则变更时同步更新

错误4:错误提示不明确

**问题:**错误提示不明确,用户不知道如何修改。

复制代码
❌ 错误示例:
错误提示:"输入错误"
问题:用户不知道哪里错了,如何修改。

✅ 正确示例:
错误提示:"用户名长度为3-20个字符,只能包含字母、数字、下划线"
说明:明确告诉用户规则,便于修改。

错误5:组合唯一性校验缺失

**问题:**需要组合唯一性的字段,只校验单个字段唯一性。

复制代码
❌ 错误示例:
商品SKU:只校验商品ID唯一性

问题:同一个商品可以有多个SKU(不同颜色、尺码)。

✅ 正确示例:
商品SKU:组合唯一(商品ID + 颜色 + 尺码)
数据库:UNIQUE KEY uk_sku (product_id, color, size)

八、最佳实践

实践1:三层校验

前端、后端、数据库三层校验,确保数据安全。

复制代码
三层校验:
1. 前端校验:用户体验优化,即时反馈
2. 后端校验:安全控制,防止绕过
3. 数据库约束:最后一道防线,数据完整性

✓ 正确做法:
- 前端:校验必填、长度、格式(用户体验)
- 后端:校验所有规则(安全控制)
- 数据库:唯一索引、检查约束(数据完整性)

✗ 错误做法:
- 只做前端校验
- 只做后端校验
- 不做数据库约束

实践2:校验规则配置化

将校验规则配置化,统一管理,便于维护。

复制代码
配置化方式:
- 使用JSON或YAML配置文件
- 前端和后端共享配置
- 校验规则变更时同步更新

示例(validation-rules.json):
{
  "username": {
    "required": true,
    "minLength": 3,
    "maxLength": 20,
    "pattern": "^[a-zA-Z0-9_]+$",
    "unique": true,
    "errorMessage": "用户名长度为3-20个字符,只能包含字母、数字、下划线"
  }
}

实践3:错误提示明确

错误提示要明确,告诉用户规则和如何修改。

复制代码
✓ 正确示例:
- "用户名长度为3-20个字符"
- "手机号格式不正确,请输入11位手机号"
- "该手机号已注册,请使用其他手机号"

✗ 错误示例:
- "输入错误"
- "格式不正确"
- "已存在"

实践4:异步唯一性校验

唯一性校验使用异步方式,避免阻塞用户输入。

复制代码
异步校验:
- 前端:失焦时调用接口检查唯一性
- 后端:查询数据库检查唯一性
- 数据库:唯一索引保证数据完整性

注意:
- 异步校验只是提示,不能完全依赖
- 最终校验在提交时进行
- 数据库唯一索引是最后一道防线

九、FAQ

Q1:前端校验够吗?

**答:**不够。前端校验只是体验优化,后端必须校验。前端可以被绕过。

为什么前端校验不够:

  • **前端代码可修改:**用户可以通过浏览器开发者工具修改前端代码
  • **接口可直接调用:**用户可以直接调用接口,绕过前端限制
  • **网络请求可拦截:**用户可以通过抓包工具拦截和修改请求

正确的做法:

  • **前端校验:**用户体验优化,即时反馈
  • **后端校验:**安全控制,防止绕过
  • **数据库约束:**最后一道防线,数据完整性

Q2:唯一性校验在哪里做?

**答:**建议数据库唯一索引 + 后端校验。前端可以失焦时调用接口提前提示。

实现方式:

  • **前端:**失焦时调用接口检查唯一性(用户体验优化)

  • **后端:**提交时查询数据库检查唯一性(业务校验)

  • **数据库:**唯一索引保证数据完整性(最后一道防线)

    示例:
    // 前端:失焦时检查
    input.onblur = async function() {
    const value = this.value;
    const exists = await checkUnique(value);
    if (exists) {
    showError('该值已存在');
    }
    };

    // 后端:提交时检查
    app.post('/api/users', async (req, res) => {
    const { username } = req.body;
    const exists = await db.query('SELECT 1 FROM users WHERE username = ?', [username]);
    if (exists.length > 0) {
    return res.status(400).json({ message: '用户名已存在' });
    }
    // 保存数据
    });

    // 数据库:唯一索引
    CREATE TABLE users (
    username VARCHAR(20) NOT NULL,
    UNIQUE KEY uk_username (username)
    );

Q3:组合唯一性怎么实现?

**答:**使用数据库联合唯一索引实现组合唯一性。

实现方式:

  • **数据库:**创建联合唯一索引

  • **后端:**提交时查询数据库检查组合唯一性

  • **前端:**选择组合字段时检查组合唯一性

    示例:商品SKU组合唯一(商品ID + 颜色 + 尺码)

    // 数据库:联合唯一索引
    CREATE TABLE product_sku (
    product_id BIGINT NOT NULL,
    color VARCHAR(20) NOT NULL,
    size VARCHAR(20) NOT NULL,
    UNIQUE KEY uk_sku (product_id, color, size)
    );

    // 后端:检查组合唯一性
    app.post('/api/product-sku', async (req, res) => {
    const { product_id, color, size } = req.body;
    const exists = await db.query(
    'SELECT 1 FROM product_sku WHERE product_id = ? AND color = ? AND size = ?',
    [product_id, color, size]
    );
    if (exists.length > 0) {
    return res.status(400).json({ message: '该规格组合已存在' });
    }
    // 保存数据
    });

Q4:校验规则怎么管理?

**答:**建议将校验规则配置化,统一管理。

管理方式:

  • **配置文件:**使用JSON或YAML配置文件管理校验规则
  • **数据库:**使用数据库存储校验规则,支持动态管理
  • **代码常量:**使用代码常量定义校验规则(适合固定规则)

推荐方式:

  • **固定规则:**使用代码常量(如手机号、邮箱格式)
  • **业务规则:**使用配置文件或数据库(如长度、范围限制)

Q5:错误提示怎么写?

**答:**错误提示要明确,告诉用户规则和如何修改。

错误提示原则:

  • **明确规则:**告诉用户具体的规则(如长度、格式)

  • **提示修改:**告诉用户如何修改(如"请输入11位手机号")

  • **避免技术术语:**使用用户能理解的语言

    ✓ 正确示例:

    • "用户名长度为3-20个字符,只能包含字母、数字、下划线"
    • "手机号格式不正确,请输入11位手机号(如:13812345678)"
    • "该手机号已注册,请使用其他手机号或http://localhost:8000/login"

    ✗ 错误示例:

    • "输入错误"
    • "格式不正确"
    • "已存在"

Q6:校验性能如何优化?

**答:**可以通过缓存、异步校验、批量校验等方式优化性能。

优化方法:

  • **缓存校验结果:**缓存唯一性校验结果,减少数据库查询
  • **异步校验:**唯一性校验使用异步方式,不阻塞用户输入
  • **批量校验:**批量操作时,批量校验,减少接口调用
  • **前端预校验:**前端先校验格式,减少后端请求
相关推荐
华清远见成都中心3 小时前
人工智能要学习的课程有哪些?
人工智能·学习
普通网友4 小时前
Bard 的模型压缩技术:在保证性能的前提下如何实现轻量化部署
人工智能·机器学习·bard
白帽子黑客罗哥4 小时前
不同就业方向(如AI、网络安全、前端开发)的具体学习路径和技能要求是什么?
人工智能·学习·web安全
捕风捉你4 小时前
【AI转行04】特征工程:治疗 AI 的“学不会”和“想太多”
人工智能·深度学习·机器学习
何贤4 小时前
2026 年程序员自救指南
人工智能·程序员·掘金技术征文
AKAMAI4 小时前
分布式边缘推理正在改变一切
人工智能·分布式·云计算
极新4 小时前
智面玄赏联合创始人李男:人工智能赋能招聘行业——从效率革新到平台经济重构|2025极新AIGC峰会演讲实录
人工智能·百度
乾元4 小时前
ISP 级别的异常洪泛检测与防护——大流量事件的 AI 自动识别与响应工程
运维·网络·人工智能·安全·web安全·架构
机器之心4 小时前
多模态推理新范式!DiffThinker:用扩散模型「画」出推理和答案
人工智能·openai
linhx5 小时前
【AIGC工作流】解构AI短剧生产管线:从手动调用DeepSeek+MJ,到Agent一站式自动化的演进
人工智能·自动化·aigc