# API 文档 ## API 概述 项目使用 Next.js API Routes 实现服务端接口,主要用于处理联系表单提交等后端逻辑。 ## 基础信息 - **基础 URL**: `/api` - **内容类型**: `application/json` - **字符编码**: `UTF-8` ## 接口列表 ### 1. 联系表单 API #### 提交联系表单 **接口地址** ``` POST /api/contact ``` **请求头** | 参数 | 类型 | 必填 | 描述 | |------|------|------|------| | Content-Type | string | 是 | application/json | **请求参数** | 参数 | 类型 | 必填 | 描述 | |------|------|------|------| | name | string | 是 | 联系人姓名 | | email | string | 是 | 联系人邮箱 | | phone | string | 否 | 联系人电话 | | subject | string | 是 | 咨询主题 | | message | string | 是 | 咨询内容 | | website | string | 否 | 蜜罐字段(用于反垃圾) | | submitTime | string | 否 | 表单提交时间戳 | | mathHash | string | 否 | 数学验证码哈希 | | mathTimestamp | string | 否 | 数学验证码时间戳 | | mathAnswer | number | 否 | 数学验证码答案 | **请求示例** ```json { "name": "张三", "email": "zhangsan@example.com", "phone": "13800138000", "subject": "产品咨询", "message": "我想了解贵公司的软件开发服务。", "submitTime": "1709827200000", "mathHash": "MTAwLTE3MDk4MjcxMDAwMDA=", "mathTimestamp": "1709827100000", "mathAnswer": 100 } ``` **响应参数** | 参数 | 类型 | 描述 | |------|------|------| | success | boolean | 请求是否成功 | | message | string | 成功消息(成功时) | | error | string | 错误消息(失败时) | **成功响应** ```json { "success": true, "message": "消息已发送,我们会尽快与您联系!" } ``` **错误响应** ```json { "success": false, "error": "请填写必填字段" } ``` **错误码说明** | HTTP 状态码 | 错误信息 | 描述 | |-------------|----------|------| | 200 | - | 蜜罐字段被填充(静默拒绝) | | 400 | 请填写必填字段 | 缺少必填字段 | | 400 | 请输入有效的邮箱地址 | 邮箱格式不正确 | | 400 | 提交过快,请稍后再试 | 提交时间间隔过短 | | 400 | 验证码错误,请重新计算 | 数学验证码错误 | | 500 | 发送失败,请稍后重试 | 邮件发送失败 | ## 安全机制 ### 1. 蜜罐字段 (Honeypot) 通过隐藏字段 `website` 检测机器人提交: ```tsx // 前端隐藏字段 // 后端检测 if (website) { // 检测到机器人,静默返回成功 return NextResponse.json({ success: true }); } ``` ### 2. 提交时间验证 验证表单提交时间间隔,防止快速自动提交: ```tsx if (submitTime) { const timeDiff = Date.now() - parseInt(submitTime); if (timeDiff < 2000) { // 提交过快,拒绝请求 return NextResponse.json({ success: false, error: '提交过快' }); } } ``` ### 3. 数学验证码 使用数学运算验证码防止机器人: ```tsx // 前端生成验证码 const num1 = Math.floor(Math.random() * 10) + 1; const num2 = Math.floor(Math.random() * 10) + 1; const answer = num1 + num2; const timestamp = Date.now(); const hash = btoa(`${answer}-${timestamp}`); // 后端验证 const expectedHash = btoa(`${mathAnswer}-${mathTimestamp}`); if (expectedHash !== mathHash) { return NextResponse.json({ success: false, error: '验证码错误' }); } ``` ### 4. 邮箱验证 验证邮箱格式: ```tsx const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { return NextResponse.json({ success: false, error: '请输入有效的邮箱地址' }); } ``` ### 5. XSS 防护 使用 DOMPurify 清理用户输入: ```tsx import DOMPurify from 'dompurify'; const sanitizedName = DOMPurify.sanitize(name); ``` ## 邮件服务 ### Resend 配置 项目使用 Resend 服务发送邮件: ```env RESEND_API_KEY=re_xxxxx COMPANY_EMAIL=contact@novalon.cn ``` ### 邮件模板 邮件使用 HTML 模板,包含: - 公司品牌头部 - 表单数据展示 - 时间戳信息 - 响应式设计 **邮件模板结构** ```html