8.4 KiB
8.4 KiB
前端API适配方案
1. 问题概述
在将后端从 PHP (ThinkPHP 6.0) 迁移到 .NET 10 的过程中,前端 UniApp 项目需要进行适配调整。主要问题包括:
- 请求格式不兼容:前端使用
application/x-www-form-urlencoded,后端期望application/json - 请求方式不一致:同一接口在不同页面使用不同的请求方式(GET/POST)
- 部分接口遗漏:如
/api/goods_list、/api/coupon等接口未正确对接
2. 当前前端请求机制分析
2.1 请求封装 (honey_box/common/request.js)
当前请求封装的关键特点:
// POST 请求使用 form-urlencoded
if (method.toUpperCase() == 'POST') {
header = {
'content-type': 'application/x-www-form-urlencoded',
// ...
}
} else {
// GET 请求使用 json
header = {
'content-type': 'application/json',
// ...
}
}
2.2 签名机制
前端对所有请求都添加了签名参数:
timestamp: 时间戳nonce: 随机字符串sign: MD5签名
签名算法:
- 参数按键名排序
- 拼接为
key=value&格式 - 添加密钥
host + timestamp - MD5 加密
3. 适配方案
方案一:前端统一改为 JSON 格式(推荐)
3.1 修改 request.js
将 POST 请求的 Content-Type 改为 application/json:
// 修改前
if (method.toUpperCase() == 'POST') {
header = {
'content-type': 'application/x-www-form-urlencoded',
// ...
}
}
// 修改后
if (method.toUpperCase() == 'POST') {
header = {
'content-type': 'application/json',
// ...
}
}
3.2 完整修改示例
static request(param, backpage, backtype) {
return new Promise((resolve, reject) => {
// ... 参数检查代码 ...
const url = param.url || ''
const method = param.method || 'POST'
const data = param.data || {}
const Loading = param.Loading || false
const token = uni.getStorageSync('token')
let client = platform.code
// ... URL 拼接代码 ...
// 添加签名参数
data.timestamp = Math.floor(Date.now() / 1000)
data.nonce = RequestManager.generateNonce()
// 生成签名
const sortedParams = {}
Object.keys(data).sort().forEach(key => {
sortedParams[key] = data[key]
})
let signStr = ''
for (const key in sortedParams) {
if (typeof sortedParams[key] === 'object') {
signStr += key + '=' + JSON.stringify(sortedParams[key]) + '&'
} else {
signStr += key + '=' + sortedParams[key] + '&'
}
}
const timestamp = data.timestamp
const appSecret = host + timestamp
signStr = signStr.substring(0, signStr.length - 1) + appSecret
const sign = md5(signStr)
data.sign = sign
// 统一使用 JSON 格式
const header = {
'content-type': 'application/json',
client: client,
token: token,
adid: uni.getStorageSync('_ad_id'),
clickid: uni.getStorageSync('_click_id')
}
// ... 发起请求代码 ...
})
}
方案二:后端兼容 form-urlencoded(备选)
如果不想修改前端,可以在后端添加中间件支持 form-urlencoded:
// 在 Program.cs 中添加
builder.Services.AddControllers()
.AddNewtonsoftJson()
.ConfigureApiBehaviorOptions(options =>
{
// 支持 form-urlencoded
});
但这种方案不推荐,因为:
- 增加后端复杂度
- 不符合 RESTful API 规范
- 后续维护困难
4. 接口请求方式统一
4.1 当前接口请求方式对照表
| 接口路径 | PHP 旧版 | C# 新版 | 前端当前使用 | 需要调整 |
|---|---|---|---|---|
/api/config |
GET/POST | GET | GET | ✅ 无需调整 |
/api/getPlatformConfig |
GET/POST | GET | GET | ✅ 无需调整 |
/api/getAdvert |
GET/POST | GET/POST | GET | ✅ 无需调整 |
/api/getDanye |
GET/POST | GET | GET | ✅ 无需调整 |
/api/goods_list |
POST | POST | POST | ✅ 无需调整 |
/api/goods_detail |
POST | POST | POST | ✅ 无需调整 |
/api/user |
POST | POST | GET | ⚠️ 需要调整 |
/api/login |
POST | POST | POST | ✅ 无需调整 |
/api/mobileLogin |
POST | POST | POST | ✅ 无需调整 |
/api/coupon_list |
POST | POST | POST | ✅ 无需调整 |
/api/order_list |
POST | POST | POST | ✅ 无需调整 |
4.2 需要调整的接口
/api/user - 获取用户信息
问题:前端 user.js 使用 GET 请求,后端期望 POST
// honey_box/common/server/user.js
// 修改前
export const getUserInfo = async () => {
const res = await RequestManager.get('/userInfo');
// ...
}
// 修改后
export const getUserInfo = async () => {
const res = await RequestManager.post('/user');
// ...
}
5. 遗漏接口清单
根据分析,以下接口可能存在问题:
5.1 商品相关
| 接口 | 状态 | 说明 |
|---|---|---|
POST /api/goods_list |
⚠️ 需检查 | 前端请求格式需改为 JSON |
POST /api/goods_detail |
⚠️ 需检查 | 前端请求格式需改为 JSON |
5.2 优惠券相关
| 接口 | 状态 | 说明 |
|---|---|---|
POST /api/coupon_list |
⚠️ 需检查 | 前端请求格式需改为 JSON |
POST /api/coupon_detail |
⚠️ 需检查 | 前端请求格式需改为 JSON |
POST /api/coupon_ling |
⚠️ 需检查 | 前端请求格式需改为 JSON |
5.3 订单相关
| 接口 | 状态 | 说明 |
|---|---|---|
POST /api/ordermoney |
⚠️ 需检查 | 前端请求格式需改为 JSON |
POST /api/orderbuy |
⚠️ 需检查 | 前端请求格式需改为 JSON |
6. 实施步骤
第一阶段:修改请求封装(核心)
- 修改
honey_box/common/request.js - 将 POST 请求的 Content-Type 改为
application/json - 测试基础接口(登录、配置获取)
第二阶段:统一接口调用方式
- 检查
honey_box/common/server/下所有接口文件 - 统一使用正确的请求方式(GET/POST)
- 确保接口路径与后端一致
第三阶段:逐模块测试
- 用户认证模块(登录、注册、绑定手机号)
- 商品模块(列表、详情、奖品)
- 订单模块(下单、支付、抽奖)
- 仓库模块(回收、发货)
- 福利模块(签到、任务)
7. 代码修改清单
7.1 honey_box/common/request.js
- header = {
- 'content-type': 'application/x-www-form-urlencoded',
- client: client,
- token: token,
- adid: uni.getStorageSync('_ad_id'),
- clickid: uni.getStorageSync('_click_id')
- }
+ header = {
+ 'content-type': 'application/json',
+ client: client,
+ token: token,
+ adid: uni.getStorageSync('_ad_id'),
+ clickid: uni.getStorageSync('_click_id')
+ }
7.2 honey_box/common/server/user.js
export const getUserInfo = async () => {
- const res = await RequestManager.get('/userInfo');
+ const res = await RequestManager.post('/user');
if (res.status == 1) {
res.data.money = common.removeTrailingZeros(res.data.money);
res.data.integral = common.removeTrailingZeros(res.data.integral);
res.data.money2 = common.removeTrailingZeros(res.data.money2);
return res.data;
} else {
return null;
}
};
8. 测试验证
8.1 测试用例
| 测试项 | 预期结果 | 实际结果 |
|---|---|---|
| 获取系统配置 | 返回配置数据 | |
| 手机号登录 | 返回 token | |
| 获取用户信息 | 返回用户数据 | |
| 获取商品列表 | 返回商品分页数据 | |
| 获取优惠券列表 | 返回优惠券数据 | |
| 创建订单 | 返回订单信息 |
8.2 调试工具
前端已集成 eruda 调试工具,可在开发环境查看网络请求详情。
9. 注意事项
- 签名机制保持不变:修改 Content-Type 不影响签名计算
- Token 传递方式不变:继续通过 header 传递
- 响应格式不变:后端返回格式与 PHP 版本保持一致
- 错误码保持一致:status 码含义不变
10. 回滚方案
如果修改后出现问题,可以:
- 恢复
request.js中的 Content-Type 为application/x-www-form-urlencoded - 在后端添加 form-urlencoded 支持中间件
- 逐步排查问题接口