✅ 4.1 RESTful API 的设计规范有哪些?常见状态码有哪些?
面试官您好,RESTful API 强调“资源”的概念,通过 URL 和 HTTP 动词组合操作资源。以下是我总结的规范:
📌 RESTful 设计规范:
项目 | 设计建议 |
---|---|
URL 命名 | 使用名词复数:/users , /posts |
动词通过方法表达 | 使用 HTTP 动词表达操作行为,如 GET 查询,POST 创建 |
状态无关性 | 每个请求都要自包含,不能依赖上一次请求状态 |
资源嵌套 | GET /users/:id/posts 表示某个用户的所有文章 |
版本控制 | 建议加 /v1/ 进行接口版本隔离 |
🧾 常见状态码(建议熟背):
状态码 | 含义 |
---|---|
200 |
OK,请求成功 |
201 |
Created,资源创建成功 |
204 |
No Content,无返回体 |
400 |
Bad Request,请求参数错误 |
401 |
Unauthorized,未认证 |
403 |
Forbidden,无权限访问 |
404 |
Not Found,资源不存在 |
500 |
Internal Server Error |
✅ 4.2 CORS 原理?如何处理跨域问题?
面试官,其实 CORS 的本质是浏览器为了安全限制不同源之间的 JS 访问资源行为。服务端通过设置响应头来告诉浏览器“允许跨域”。
🌐 CORS 原理简述:
浏览器发起跨域请求时,会先发送 预检请求(OPTIONS)
服务端需返回如下头部:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
🔧 如何处理跨域?
Express 中:
const cors = require('cors');
app.use(cors({
origin: 'http://localhost:3000',
credentials: true
}));
NestJS 中:
app.enableCors({
origin: 'http://localhost:3000',
credentials: true
});
其他方式(了解加分):
方法 | 是否推荐 | 原理简述 |
---|---|---|
JSONP | ❌ | 只能 GET ,非标准方式 |
Nginx 反向代理 | ✅ | 同源请求避免跨域限制 |
CORS 标准协议 | ✅✅ | 推荐,现代浏览器通用方法 |
✅ 4.3 前端如何处理 token 过期?服务端如何刷新 token?
在生产项目中,我们通常使用 JWT + Refresh Token 双 token 机制。前端检测到 token 过期,就通过刷新接口获取新的 token。
🧩 前端处理策略:
JWT 过期后,调用
/auth/refresh
接口获取新 token;请求失败时统一拦截(Axios 拦截器);
刷新成功后重试原请求。
axios.interceptors.response.use(undefined, async error => {
if (error.response.status === 401) {
const newToken = await refreshToken();
// 更新 token 重试原请求
}
});
🛡 服务端刷新流程:
1. 登录成功后下发 Access Token + Refresh Token(存 HttpOnly Cookie)
2. 客户端每次携带 Access Token
3. 若 Access Token 过期,调用 refresh 接口,服务端验证 Refresh Token
4. 若合法,颁发新的 Access Token
Refresh Token 通常设置较长有效期,并存储于数据库或 Redis 中,用于回收与吊销。
✅ 4.4 如何设计一个登录注册流程?包括验证码、加密、Token
这是经典综合题,我从注册、验证码、加密、登录鉴权四个步骤讲解:
🟩 注册流程:
用户填写信息(手机号 / 邮箱)
服务端发送验证码(短信 / 邮件),并存入 Redis
用户填写验证码,服务端验证
对密码加密(bcrypt),写入数据库
const hash = await bcrypt.hash(password, 10);
await userRepository.save({ username, password: hash });
🟨 登录流程:
用户提交账号密码
验证账号是否存在
使用
bcrypt.compare()
验证密码登录成功后签发 JWT,返回前端:
const token = jwt.sign({ uid: user.id }, 'secret', { expiresIn: '1h' });
🔐 加密方式:
类型 | 用途 |
---|---|
bcrypt | 密码加密(单向) |
AES | 对称加密 |
RSA | 非对称加密 |
🔁 Token 存储建议:
Access Token 存
localStorage
/sessionStorage
Refresh Token 建议存在 HttpOnly Cookie,防止 XSS 攻击
✅ 4.5 前后端接口联调过程中常见问题和解决方式?
在我实际开发中,经常遇到接口联调过程中的各种问题。下面列出几个典型场景和我的处理经验:
🔍 常见问题 & 解决方案:
问题类型 | 描述 | 解决方式 |
---|---|---|
❌ 跨域问题 | 浏览器拦截,OPTIONS 请求失败 | 服务端设置 Access-Control-* 头部 |
❌ 参数格式错误 | 前端传 JSON,后端解析失败 | 确保 Content-Type 一致 |
❌ 鉴权失败 | Token 丢失、过期、签名无效 | 设置 Axios 全局请求头 + 统一刷新处理 |
❌ 状态码不规范 | 返回 200,但实际是失败 | 后端规范状态码,并用 code + msg 返回 |
❌ Mock 与接口不一致 | Mock 返回结构与实际接口不同 | 与后端同步接口文档,统一 OpenAPI 规范 |
🧰 建议工具:
使用 Postman / Swagger 文档进行调试
使用 TypeScript 共享类型定义
使用 Mock 服务(如
Mock Service Worker
)提前模拟数据
✅ 总结:
问题编号 | 涉及知识点 |
---|---|
4.1 | RESTful 设计、状态码规范 |
4.2 | 跨域原理、服务端 CORS 设置 |
4.3 | Token 过期检测、刷新机制 |
4.4 | 登录注册流程、验证码、加密与鉴权 |
4.5 | 联调常见问题排查与实践经验 |