Open
Description
遵守约定,可以避免一些不必要的歧义,降低前后端沟通成本。
前后端配合开发流程
划分前后端工作界限,避免前后端工作节奏被相互影响;并行开发之前,一定要确定好接口!!!
- 前后端理解需求,前端进行部分页面开发,技术难点攻克;后端进行需求分析、数据库设计,确定绝大部分字段名称、类型、各式、描述等;
- 基于原型/文档,后端设计接口,基于restfull形成接口文档(swagger),前端确认后端接口是否符合前端需求。需要确认内容如下:
- 每一个页面都需要哪些请求,哪些是以前提供过,哪些没有提供过;
- 请求方法类型,确认使用get还是post等;
- 请求的url;
- 请求参数结构、参数名、类型;
- 返回数据结构、变量名、类型;
- 前端基于约定好的接口文档进行页面开发;后端进行业务开发,提供真实数据接口。接口规范定义之后,后期如有变动及时沟通;
- 前后端进行联调:后端验证接口是否正确,前端提供技术支持;
前后端界限(任务分工)
前端负责展示,后端负责数据处理;不要让前端进行数据的拼接,筛选等操作。
- 前端
- 展示后端传递数据,一般不需进行处理就可以直接展示;
- 处理用户交互,收集数据发送ajax请求;
- 后端工作
- 处理业务逻辑,编写api接口,为前端提供数据;
- code 转 name,同时保留原先的code,前端转换会发送过多的请求,影响展现性能;
- 页面中多个零散请求,如果可行,合并成一个请求,减少页面请求数量,提高页面展现性能;
ajax约定
数据交互统一使用JSON。
请求约定
基于restfull设计请求url。
- 正确区分get post put del 等请求含义:
- get: 获取服务端数据;
- post: 保存数据到服务端;
- put: 修改服务端数据;
- del: 删除服务端数据;
- 列表页分页参数:
- 页容量:
pageSize
; - 页码:
pageNum
;
- 页容量:
- 同一个数据出现在任何位置,要统一参数名;比如:房间号
roomNo
,不要出现roomNum
、roomCode
等其他参数名; - 如无特殊需求,传递时间数据,要统一时间格式;
- 后端需要的参数,要声明字段名、类型、各式(时间)、描述(中文说明字段含义);
成功时返回数据结构
通过message可以统一多端提示,如果提示信息需要更改,只改接口,各个端不需要修改,不需要发布。
- code:业务逻辑结果编码,前端一般用不到,也可以通过code约定成功还是失败;
- message:后端提供的信息,用于展现给用户,错误提示或者成功提示;成功提示如果后端统一给出,那么可以统一各个端(pc、android、ios)的提示信息,要区分开发、生产模式,开发过程中给出完整的错误提示,便于定位错误,生产环境给出用户友好提示并隐藏错误细节;
- error:后端详细异常对象(或者字符串),用来体现具体的后端错误信息,方便定位问题,只非生产环境提供,生产环境不提供,以免暴露后端细节;
- data:数据,单个数据为json对象、基本数据类型,多条数据为json数组,数据变量命名规则如下:
- 数据变量驼峰式命名;
- 数据不必加前缀,比如用户查询,直接返回
id
、name
、account
即可,直接数据对象的属性,不必添加user前缀,不要写成userId
、userName
、userAccount
; - 如果是其他对象属性,需要加前缀区分,比如user对象中有角色
id
,角色id要命名成roleId
; - 同一个数据,无论出现在哪个接口里面,要保证命名统一,减少歧义及沟通成本;比如:
roomNum
房号,不要出现roomNo
、roomCode
等多个命名; - 码表型数据,对应
code
要转成对应的中文,命名以Name
结尾,同时保留原有code(多数业务需要用到原code),比如:roomCode
,同时提供roomCodeName
用于显示; - 时间用于展示,直接格式化成要显示的格式,最好提供原时间的时间戳。如果不提供格式化后的数据,需要提供时间戳,前端可以自己格式化,不要提供其他格式日期,前端格式化时,容易出错;
- 列表数据,每条件记录以
id
为唯一标识;一定要存在id
属性; - 每一个字段要给出描述,不常见字段前端并不知道对应的是什么,沟通成本比较高;
- total:总条数,分页页面会用到;
- 其他约定字段等;
失败时返回数据结构
接口调用失败、后端逻辑验证失败等,后端要返回错误信息;
- 所有非预期成功结果都视为失败,比如校验错误、越权操作等。
- 后端要基于不同的开发模式,返回不同的错误提示,生产环境返回友好的用户提示(message);其他环境返回用户提示(message)+具体错误信息(error),方便调试。
- 合理使用http状态码,前端会根据不同的http状态码进行不同的操作,详见如下 http状态码约定;
http状态码约定:
基于不同的状态码,前端会有相应的封装
- 200:正常业务逻辑,不包含校验错误等业务逻辑,200一定是预期的成功;
- 400:业务逻辑错误,校验错误,后端主动抛出的错误等,也可以约定为其他cod,视情况而定;
- 401:需要登录,前端发现ajax返回401,会跳转到登录页面;
- 403:无权操作,前端一般会给出类似“无权操作”的提示;
- 404:资源不存在,前端一般会给出类似“您访问的资源不存在”的提示;
- 500:服务端异常,前端一般会给出“未知系统错误,请联系管理员”;
后端解决跨域
跨域问题由服务端配置或NG代理进行解决,更简单一些。只是开发过程中会遇到跨域问题,实际生产环境使用NG,解决了跨域问题;
- header一些设置,以nodejs为例:
app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", config().allow_origin); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); res.header("Access-Control-Allow-Credentials", "true"); res.header("X-Powered-By", ' 3.2.1') res.header("Content-Type", "application/json;charset=utf-8"); next(); });
- cookie问题: ajax跨域请求中的cookie问题;
- 后端
Access-Control-Allow-Origin
不能设置成*,要指定具体的域名; - 前端ajax请求,要设置
withCredentials
为true
,允许跨域的cookie访问;
- 后端
通过配置proxy解决跨域
前端开发会启动一个开发模式的服务,如果这个服务支持proxy配置,可以通过配置proxy解决跨域问题
"proxy": {
"/api": {
"target": "http://localhost:3000"
}
}