七、Git
7.1 Git工程规范
#7.1.1 Git flow规范
在工作中避免不了多人协作,协作避免不了有一个规范的流程,让大家有效的去合作;让项目仅仅有条的发展下去;git flow是最早诞生, 并得到广泛采用的一种工作流,git flow采用的是功能驱动式开发。 功能驱动式开发(Feature-driven development,简称FDD)
-
长期分支
- master - 主分支
- develop - 开发分支
-
短期分支
- feature - 功能分支
- hotfix - 补丁分支
- release - 预发分支
| 分支 | 详细介绍 |
|---|---|
| master | 产品分支:只能从其他分支合并内容,不能在这个分支直接修改。合并到master上的commmit只能来字release分支或hotfix分支 |
| develop | 开发主干分支:基于master的tag建立,主要用来暂时保存开发完成而又未发布的feature分支内容,以及release和hotfix的补充内容 |
| feature | 功能分支:一般一个新功能对应一个功能分支,从而和已经完成的功能隔离开来,而且只有在新功能完成开发的情况下,其对应的feature分支才会合并到主开发分支(develop分支)上 |
| release | 预发分支:当需要发布时,我们从develop分支创建一个release分支,然后这个release分支会发布到测试环境进行测试,如果发现问题就在这个分支直接进行修复。发布结束后,这个release分支会合并到develop和master分支,从而保证不会有代码丢失。 |
| hotfix | 补丁分支:主要用于紧急修复一些bug,会从master分支上的某一个tag建立,修复结束后再合并到develop和master分支上 |
7.1.2 Git commit 规范
#为什么要写好 Git Commit?
- 提供更多的历史信息,方便快速浏览
- 可以过滤某些commit(比如文档改动),方便快速查找信息
# 过滤日志信息
git log HEAD --pretty=format:%s --grep 关键字
- 可以直接从commit生成Change log
如何优雅地写好Git Commit
业界使用比较广泛的是Angular规范
<type>(<scope>):<subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
- 标题行:必填,描述主要修改类型和内容
- 主要内容:描述为什么修改,做什么样的修改,以及开发的思路等等
- 页脚注释:放 Breaking Changes 或 Closed Issuses
type | commit 类型
| 类型 | 详细介绍 |
|---|---|
| feat | 新功能、新特性 |
| fix | bugfix,修改问题 |
| refactor | 代码重构 |
| docs | 文档修改 |
| style | 代码格式修改,注意不是css修改 |
| test | 测试用例修改 |
| chore | 其他修改,比如构建,依赖管理 |
scope | commit影响的范围 比如:route、component、utils、build.....
- subject:commit 的概述,建议符合 50/72 formatting
- body:commit 具体修改内容,可以分为多行,建议符合50/72 formatting
- footer:一些备注,通常是BREAKING CHANGE 或 修改的bug链接
#利用插件(commitizen)
利用commitizen,提交规范的commit。
- commitizen 用于提示用户输入或选择,生成规范的commit
- cz-conventional-changelog 用于生成changelog
# 1. 下载cz-conventional-changelog changelog插件
npm install -g commitizen cz-conventional-changelog
# 2. package.json 配置
{
"scripts": {
# 以后提交commit 直接执行npm run commit
"commit": "git-cz",
},
# config用来设置一些项目不怎么变化的项目配置,用户用的时候可以使用如下用法:process.env.npm_package_config_commitizen
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
# 也可以使用以下配置,配置全局变量
# 命令行中输入以下命令,配置到czrc目录下,也可以用vim编辑~/.cz
echo '{ "path": "cz-conventional-changelog"}' > ~/.czrc
自定义文档格式,commit用中文去写(扩展)
# 1.下载
npm install -g cz-customizable
# 2. package.json 配置
...
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
},
"cz-customizable": {
"config": "./cz.config.js"
}
}
# 也可以使用以下配置,配置全局变量
echo '{ "path": "cz-customizable"}' > ~/.czrc
# echo添加或vim编辑添加
vim .czrc
# 添加配置 { "path": "cz-customizable"}
# 3.创建配置文件
touch ./cz.config.js
cz.config.js
module.exports = {
//可选类型
types: [
{ value: 'feat', name: 'feat: 新功能' },
{ value: 'fix', name: 'fix: 修复' },
{ value: 'docs', name: 'docs: 文档变更' },
{ value: 'style', name: 'style: 代码格式(不影响代码运行的变动)' },
{
value: 'refactor',
name: 'refactor:重构(既不是增加feature),也不是修复bug'
},
{ value: 'perf', name: 'perf: 性能优化' },
{ value: 'test', name: 'test: 增加测试' },
{ value: 'chore', name: 'chore: 构建过程或辅助功能的变动' },
{ value: 'revert', name: 'revert: 回退' },
{ value: 'build', name: 'build: 打包' },
{ value: 'revert', name: 'revert: 回退' }
],
//消息步骤
messages: {
type: '请选择提交类型',
customScope: '请输入修改范围(可选)',
subject: '请简要描述提交(必填)',
body: '请输入详细描述(可选)',
footer: '请输入要关闭的issue(可选)',
confirmCommit: '确认以上信息提交?(y/n)'
},
//跳过问题
skipQuestion: ['body', 'footer'],
//subject文字长度默认是
subjectLimit: 72
}
gitmoji(趣味图标)(扩展)
npm i -g gitmoji-cli
gitmoji -c # git commit 提交
7.2 Git Hooks
#7.2.1 git hooks
Git 钩子(hooks)是在Git仓库中特定事件(certain points)触发后被调用的脚本
可以用git init初始化git文件,在.git/hooks下有各种钩子模版,可以用例如less prepare-commit-msg.sample查看文件,里面是一段执行脚本。
- 客户端钩子-> 由诸如提交和合并这样的操作所调用
- 服务端钩子-> 作用于诸如接收被推送的提交这样的联网操作
#客户端 Hooks
| 类型 | 详细介绍 |
|---|---|
| prepare-commit-msg | commit message编辑器呼起前 default commit message创建后触发,常用于生成默认的标准化的提交说明 |
| commit-msg | 开发者编写完并确认commit message后触发,常用于校验提交说明是否标准 |
| post-commit | 整个git commit完成后触发,常用于邮件通知、提醒 |
| applypatch-msg | git am提取补丁并 应用于当前分支后,准备提交触发,常用于执行测试用例或检查缓冲区代码 |
| pre-applypatch | git am提交后触发,常用于通知、补丁、邮件推送回复(此钩子不能停止git am过程) |
| pre-rebase | 执行git rebase命令时触发 |
| post-rewrite | 执行会替换commit的命令时触发,比如git rebase 或 git cimmit-amend |
| post-checkout | 执行git checkout命令成功后触发,可用于生成特定文档,处理大二进制文件等 |
| post-merge | 成功完成一次merge行为后触发 |
| pre-auto-gc | 执行垃圾回收前触发 |
#服务端 Hooks
| 类型 | 详细介绍 |
|---|---|
| pre-receive | 当服务端收到一个push操作请求时触发,可用于检测push的内容 |
| update | 与pre-receive相似,但当一次push想更新多个分支时,pre-receive只执行一次,而此钩子会为没一分支都执行一次 |
| post-receive | 当整个push操作完成时触发,常用于服务侧同步、通知 |
7.2.2 工程实践
#Husky
用node实现的的快速安装git hooks的工具
// npm install husky --save-dev
// package.json
{
"husky" : {
"hooks": {
"pre-commit": "npm test",
// ......
}
}
}
命令行 less .git/hooks/pre-commit 查看pre-commit文件,可以看见"0")/husky.sh",然后可以查看less .git/hooks/husky.sh
#link-staged
只会检测暂存区的文件,不会对所有的文件进行检测,也就是说我修改一个文件,只会检测当前这个文件
# 安装代码检测工具
npm install prettier eslint -D
# 安装lint-staged
npx mrm lint-staged
{
"gitHooks": {
"pre-commit": "lint-staged"
},
{
"lint-staged": {
"*.js": "eslint --cache --fix",
"*.{js,css,md}": "prettier --write"
}
}
7.2.3 Git Hooks 拓展学习资料
自定义Git - Git 钩子:git-scm.com/book/zh/v2/…
Husky:github.com/typicode/hu…
8.1 真机远程代码调试
#8.1.1 ios真机设备调试
- 在手机上开启网页检查器
设置-> safari 浏览器 -> 高级 -> 网页检测器
- 开启Safari上的Develop功能
菜单 -> Preferences(偏好设置) -> Advanced(高级)
3. 使用数据线连接手机个开发主机
- 信任电脑
- 打开devTool
Develop -> 你的ios设备 -> 要调试的页面
8.1.2 Android真机设备调试
- 在手机上开启USB调试功能
设置-> 开发者选项 -> USB调试
- 使用数据线连接手机和开发主机
- 允许USB调试
- 打开Chrome DevTools
- 在地址栏输入chrome://inspect
- 确保开启了 Discover USB devices
#8.2 无线调试工具-Weinre
- 无需数据线
- pc和移动都可以调试
- 环境准备与安装
- 环境:任何node.js 环境
- 安装:
npm install -g weinre
weinre -h #获取帮助信息
weinre --boundHost=-all- --httpPort=1000 # 启动,boundHost为all是允许本机所有有效ip访问,默认端口8080
- 浏览打开:ip:1000 或 http://localhost:1000/
2. arget 页面配置
<!-- 往被调试页面添加脚本 -->
<script src="http://ip:端口/target/target-script-min.js#anonymous"></script>
<!-- 示例 -->
<script src="http://172.20.10.11:1000/target/target-script-min.js#anonymous"></script>
- 调试
调试移动手机的页面需要手机访问局域网内的页面服务(例如react开启了3000端口的服务,那么手机访问ip+3000)
扩展
#8.3 在移动端调试
主流的移动端devTool
- vConsole
- eruda
扩展资料
#8.4 使用代理服务器进行调试(charles)
#8.4.1 常见的代理服务器
-
Fiddler
- C#编写
- 正式版仅支持Windows
- 请求展示:时间顺序
- 支持解析HTTPS请求
- 免费
-
Charles
- java编写
- 多平台支持
- 请求展示:树状结构
- 不支持直接解析HTTPS请求
- 付费获得更好体验
8.4.2 HTTP抓包
- 移动端配置(配置代理)
点击手机连接的Wi-Fi->HTTP代理->配置代理
- 服务器:填入电脑的ip地址(可以在charles查看 help->Local IP Address)
- 端口:默认是8888
- 开始抓包
工具栏第二个按钮(红色说明正在抓包)
#8.4.3 HTTPS抓包
charles不能直接抓包https,所以我们还需要进行以下操作
- 移动端配置代理
与上面http配置完全相同 (切记!!!这一步一定要做,只有配置了代理服务,才能下载证书,因为这是你电脑上charles给你颁发的,你换了电脑还需要另一个电脑给你颁发)
- 添加要解析的域名列表
- 菜单栏Proxy-> SSL Proxying Settings
- 在Host一栏设置要解析的域名,也可以*表示所有的HTTPS都做解析,port:443;点击ok后重启charles。
设置后重启charles
- 信任Charles根证书
-
在移动端用浏览器访问
https:chls.pro/ssl下载证书描述文件-
安卓:直接安装即可
-
IOS:
- 在设置-通用-描述文件与设置管理中安装证书,
- 然后开启 设置-通用-关于本机-针对根证书启用完全信任
-
(当你访问上面chls网站时,电脑上charles会有一个弹窗询问你是否允许给手机安装证书,你要点同意(allow))
🍅 HTTPS 协议
- https = http + sll(secure sockets layer)
发送一个HTTPS请求的过程简单来说客户端是向服务端索取一个公钥放在客户端,公钥的载体就是数字证书;客户端通过公钥加密,服务端通过私钥解密。
🍅 charles 代理HTTPS请求的机制
charles做客户端和服务端的中介,代理了https请求;charles会动态为每个服务器生成由charles根证书签发的数字证书;当请求产生时客户端收到的不是 服务端的原始证书而是charles签发的证书,原始证书是保存在charles上的;客户端与服务端的通信是由charles公钥加密的,而charles与原始服务器的通信是 由服务端的原始证书加密的,charles通过自己的私钥解密,所以我们能通过charles看见未加密的数据。
🍅 可能出现的问题
- 开启后电脑浏览器无法打开网页
关掉charles的External Proxy setting:点击顶部Proxy-> 去掉勾选 External Proxy Settings
-
开启手机代理后浏览器无法打开网页
- 要保证电脑和手机同一个Wi-Fi,手机上填的代理服务器ip不要填错了,可以查看charles:Help/Local IP Address;端口一般是8888
- 打开https的网站,会提醒不是安全连接,说明你证书没有安装正确,或者没有信任
- 一般就上诉2个问题,也可以重启试试
-
关闭charles后 无法联网
打开网络偏好设置-> 高级 -> 代理 -> 检测网页代理和安全网页代理是否开启(不需要开启,你关闭charles后就没有代理服务器了,记得手机也取消代理配置)
- 抓取手机端的返回的是unknow
- 确保证书在手机端被信任
- safari浏览器访问
https:chls.pro/ssl下载证书描述文件时候,确保配置了http代理(ip:8888), 如果换电脑需要再次下载证书,可以在描述文件中查看证书,charles通用名称中会包含你电脑系统的名称
- 手机开启代理后,也能访问网页,但是电脑上的charles没有抓取到数据
- 检查代理是否正确
- 重启charles
8.4.4 Map请求重定向
🍅 Map Local / Map Remote
- 生产环境代码打包压缩后不利于debug
- 调试时不方便频繁发布
Map Local:将某请求重定向至本地某个文件Map Remote:将某请求重定向至另一个请求- 将生成环境的代码替换成本地的代码
🍅 Map Remote
尝试改动代码,查看页面变化
🍅 Map Local
Map Local可以替换任意charles能抓包到的文件,甚至可以将api请求替换成本地的json文件,做接口的一个mock, 其实就是一个文件的代理功能。
如果想取消Map Local / Map Remote:charles顶部tools-> Map Local / Map Remote -> 不勾选enable map local/Remote-> ok
8.4.5 Rewrite 修改请求内容
🍅 Rewrite功能
- 可作用于:request & reponses
- 可修改:header、host、path、url、params、body等
- 采用新增、替换的形式
🍅 案例
向生产环境页面注入vConsole脚本
- 顶部tools-> Rewrite
添加匹配location
添加rewrite规则
上面其实就是将</head>标签替换成 <script src="<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/2.5.0/vconsole.min.js"></script>">new VConsole()</script></head>
8.5 在公网访问本地服务
#8.5.1 内网穿透
#什么叫内网穿透
-
NAT(Network Address Translation)穿透
-
从公网访问内网
-
在公网访问部署在本地服务器上的服务
-
ngrok & localtunnel
- 生成唯一可在公网访问的url,该url会在代理本地运行的web服务请求
#8.5.2 localtunnel的使用
- 安装
npm install -g localtunnel
lt --help # 帮助信息
- 启动
# -p 本地启动服务的端口,-s 指定自己子域名地址,也可以不指定
lt -p 3000 -h https://tunnel.svrx.io -s mayi
# 启动成功后 your url is: https://mayi.tunnel.svrx.io
# 访问地址 https://mayi.tunnel.svrx.io
8.5.3 部署你的localtunnel服务
-
localtunnel默认服务在外国,不稳定,访问速度慢
-
自己部署lt服务的机器需要满足:
- 支持DNS泛域名解析,比如:mydomain.com 和 *.mydomain.com
- Localtunnel服务端能监听任何非root权限的TCP端口
-
配置dns解析 添加两个A类记录
- mydomain.com
- *.mydomain.com
-
启动localtunnel server
git clone git://github.com/defunctzombie/localtunnel-server.git
cd localtunnel-server
npm install
bin/server --port 1234
bin/server --port 1234 --domain sub.mydomain.com
- 在localtunnel客户端使用部署的host
lt --host http://sub.mydomain.com:1234 --port 8000
8.6 随机数据生成(mock)
#特点
- “生成随机数据,拦截Ajax请求“
- 业务代码物侵入
- 数据类型丰富
- 用法简单,可扩展性强
#8.6.1 Mock.js 的安装及基本语法
// 安装
npm install mockjs
// 基本用法
const Mock = require('mockjs')
const data = Mock.mock({
// 属性list 的值是一个数组,其中含有 1 到 10个元素,数组里的对象数量是随机的
'list|1-10':[{
// 属性id 是一个子增函数,起始值为1,每次增1
'id|+1':1
}]
})
// 输出结果
console.log(JSON.stringify(data,null,4))
mockjs的语法
// name 是属性名,rule是规则 ,value是属性值;属性名和规则之间是用|分割的
'name|rule': value
name: value
1. 'name|min-max': value
2. 'name|count': value
3. 'name|min-max.dmin-dmax': value
4. 'name|min-max.dcount': value
5. 'name|count.dmin-dmax': value
6. 'name|count.dcount': value
7. 'name|+step': value
- 属性值决定了规则的初始值和类型
- 生成规则的含义需要依赖属性值的类型才能确定
- 属性值是字符串
- 将value字符串重复min-max次
// 1. 'name|min-max': value 生成的数量是随机的
{'repeater|1-5': 'hi!'} -> { repeater: 'hi!hi!hi!'}
- 将value字符串重复count次
// 2. 'name|count': value
{'repeater|2': 'hi!'} -> {repeater: 'hi!hi!'}
- 属性值是数字
- 随机生成min-max 范围内的一个数字
// 1. 'name|min-max': value
// 现在value是数字,属性值决定了初始值,1和50也可以换成其他数字;不影响结果
{'age|1-30': 1} -> { age: 22 }
{'age|1-30': 50} -> { age:15 }
- 随机生成一个小数,整数部分值在min-max范围内,小数部分位数在dmin-dmax之间
// 'name|min-max.dmin-dmax':vlaue
{ 'price|1-30.2-3': 1} -> { price: 20.28}
{ 'price|1-30.2-3': 1} -> { price: 4.827}
- 属性值是布尔值
-
随机生成一个布尔值,其中value和!value的比例为min-max
- value 概率 = min / (min+max)
- !value 概率 = max / (min + max)
// 'name|min-max':vlaue
{ 'active|1-1': true } -> { active: true }
{ 'active|1-1': true } -> { active: true }
- 属性值是对象
- 从value中随机min-max个属性
// 'name|min-max': vaule
{ 'user|1-2': { name: 'jack', age: 2 }} -> { user: { age:2}}
{ 'use|1-2': { name: 'jack', age: 2 }} -> { user: { name: 'jack', age:2 }}
- 从value中随机取count个属性
// 从value中随机取count个属性
// ‘name|count’: value
{ 'user|1': { name: 'jack', age: 2}} -> { user: { age:2 }}
- 属性值是数组
- 从value列表中随机获取1个元素
{ 'fruit|1': ['apple','banana']} -> { fruit: 'banana' }
- 将value列表内的值重复min-max次
{ 'list|1-2': ['a']} -> { list: ['a']}
{ 'list|1-2': ['a']} -> { list: ['a','a']}
- 属性值是其它类型
- 生成值为function执行结果
// function
{ age: ()=> 1 } -> { age:1 }
- 随机生成符合正则表达式的字符串
// reExp
{ age: /1[0-9]/ } -> { age: '19' }
8.6.2 Mock.js的常用方法
- Mock.mock()
-
Mock.mock(rurl?,rtype?,template|function(options))
- rurl: 要拦截的请求url,支持正则
- rtype:要拦截的请求类型,如POST、GET、DELETE等
- template:数据模版,支持对象、字符串
- function(options): 生成相应数据的方法,options:{ url,type,body }
🍅 使用mock()方法拦截请求
// 在入口文件中引入mockjs,对 ‘api/activity‘进行拦截
import Mock from 'mockjs';
if(process.env.NODE_ENV !== 'production')
Mock.mock(/api/activity/,{
code: 200,
data: {
'isLegal|2-1':false
}
})
}
- Mock.Random
- 工具类
const { Random } = Mock;
Random.email()
// => "n.abc.@miller.io"
Random.image()
// => http://dummyimage.com/336x330
🍅 Mock.Random 支持的方法
| type | Method |
|---|---|
| Basic | boolean、natural、integer、float、character、string、range、date、time、datetime、now |
| Image | image、dateImage |
| Color | color |
| Text | paragraph、sentence、word、title、cparagraph |
| Name | first、last、name、cfirst、clast、cname |
| Web | url、domain、email、ip、tld |
| Address | area、region |
| Helper | capitalize、upper、lower、pick、shuffle |
| Miscellaneous | guid、id |
🍅 Mock.Random 与模版语法
const Mock = require('mockjs');
const { Random } = Mock
const user = Mock.mock({
code: '200',
'list|10': [{
name: `${Random.first()} ${Random.last()}`,
avatar: Random.image()
}]
})
console.log(users)
{
code: 200,
list: [
{ name:'Sarah Leris', avatar: 'http://dummyimage.com/300x600'},
{ name:'Sarah Leris', avatar: 'http://dummyimage.com/300x600'}
.....
]
}
// 10个相同的对象
由于用Random生成的都是一样的,这可能不是我们想要的,我们想要每一个对象里的数据都不一样,那就看下面的占位符。
🍅 Mock.js 的占位符
- 占位符
- 使用最广泛
- @占位符
- @占位符(参数、[,参数])
- 只是在属性值字符串中占个位置,并不出现在最终的属性值中
- 实际采用Random中的方法计算
const Mock = require('mockjs');
const { Random } = Mock
const user = Mock.mock({
code: '200',
'list|10': [{
name: '@first @last',
avatar: '@image'
}]
})
console.log(users)
{
code: 200,
list: [
{ name:'Carol Brown', avatar: 'http://dummyimage.com/3335x220'},
{ name:'Angela Lopez', avatar: 'http://dummyimage.com/378x600'}
.....
]
}
// 10个不同的对象
8.7 RestFul API 快速模拟
#8.7.1 复杂的接口mock场景
#RESTful API
- REpresentational State Transfer 表现层
- 资源是由URI来指定:/songs(代表歌曲) /playlist/12(代表第12个playlist)
- 对资源的操作包括增删改查:POST、DELETE、PUT和GET方法
- 是一套API设计理论,约束规范、增强可读性、便于开发
#RESTful 规范
GET http://abc.com/api/playlists # 获取歌单列表
GET http://abc.com/api/playlist/12345 # 获取id为123456的歌单
POST http://abc.com/api/playlists # 添加一个歌单
DELETE http://music.163.com/api/palylist/55 # 删除id为 55 的歌单
PUT http://music.163.com/api/palylist/123456 # 删除id为 123456 的歌单
GET : 返回资源对象
POST :返回新生成的资源对象
PUT :返回完整的资源对象
DELETE:返回一个空文档
{
"code": 200,
"message": "success",
"data": {
playlist: {....}
}
}
HTTP 状态码:
2xx: 请求成功
3xx:重定向
4xx:客户端错误
5xx:服务端错误
- 如何mock对同一个资源的增删改查
- 在前端运行、可以存储数据的server
- JSON-Server :零开发,快速模拟RESTful API
#8.7.2 JSON-server 的安装和用法
// install
npm install -g json-server
// db.json
{
"songs":[
{ "id": 1, "name": "Baby"}
],
"comments": [
{ "id": 1, "content": "nice" }
]
}
// start server
json-server --watch db.json
运行成功输出的日志
{^_^}/ hi!
Loading ./db.json
Done
Resources
http://localhost:3000/songs
http://localhost:3000/comments
Home
http://localhost:3000
Type s + enter at any time to create a snapshot of the database
Watching...
GET /songs 200 8.036 ms - 43
GET /songs 304 3.381 ms - -
GET http://localhost:3000/songs/1 会返回 { "id":1,"name":"Baby"} 根据songs/1路由1进行筛选
POST、PUT、PATCH、DELETE 操作会改变db.json文件的内容 Routes 规则-过滤
{
"songs": [
{ "name": "吻别", "artist": "张学友" },
{ "name": "燃烧我的卡路里 ", "artist": "火箭少女 101" },
{ "name": "麻雀", "artist": "李荣浩" }
],
"comments": [
{ "id": 1, "content": "nice" }
]
}
GET /songs?artist=张学友
GET /songs?artist=张学友&arttist=李荣浩
GET /comments?author.id=1
🍅 Routes 规则-翻页与排序
// 以_开头的是json-server的保留字
// 分页
GET /songs?_page=2
GET /songs?_page=1&_limit=15
// 排序
GET /songs?_sort=id&_order=asc
// 多字段排序
GET /songs/_sort=id,name&_order=desc,asc
🍅 Routes 规则-查询
// operators:
// _gte _lte _ne 大约小于等于
GET /users?age_gte=10&age_lte=20
GET /users?age_ne=18
// _like 支持正则
GET /songs?name_like=爱
// q 全局搜索
GET /songs?q=喜欢
🍅 自定义 routes
- 更贴近后端接口
// routes.json
// 左边是实际访问的路径,右边是资源的路径
{
"/api/*": "/$1",
"/:resource/:id/show": "/:resource/:id",
"/posts/:category": "/posts?category=:cagegory",
"/articles\?id=:id": "/posts/:id"
}
// 添加启动参数:json-server db.json --routes routes.json
/api/posts // -> /posts
/api/posts/1 // -> /posts/1
/posts/1/show // -> /posts/1
/posts/javascript // -> posts?category=javascript
/articles?id=1 // -> /posts/1
🍅 添加 middleware
- 统一定制个性化请求
// my-middleware.js
module.exports= (req, res ,next) => {
res.header('X-token',"xxxxx")
next()
}
// 启动
json-server db.json --middlewares ./my-middleware.js
8.7.3 生成随机数据
当数据量过大时候,我们不能手写庞大数据量的db.json,json-server也支持js对象。
快速生成随机数据-Mock.js
// index.js
const Mock = require('mock.js')
module.exports= () => {
const data = Mock.mock({
'user|1000': [{{
'id|+1': 1,
'name': '@first @last'
}]
})
return data
}
// 启动
json-server index.js --middlewares ./my-middleware.js
#8.7.4 JSON-Server的基本使用
搭配Mock.js 生成随机数据接口
🍅 查询歌单列表
新建文件index.js
const Mock = require('mockjs')
module.exports= ()=> {
const data = Mock.mock({
'playlists|100': [{
'id|+1':1,
'name': '@title',
'cover': '@image'
}]
})
return data
}
新建routes.json
// /api/music/ 下面所有的请求转发到去掉这个前缀的下面
// $1 表示任意的字符
{
"/api/music/*": "/$1"
}
启动 json-server index.js --routes routes.json
访问 http://localhost:3000/api/music/playlists可以获得100条数据
🍅 查询分页的歌单
修改routes.json
{
"/api/music/*": "/$1",
"/playlists\?limit=:limit&offset=:offset": "/playlists?_start=:offset&_limit=:limit"
}
启动 json-server index.js --routes routes.json
访问 http://localhost:3000/api/music/playlists?limit=10&offset=20从20开始返回10条数据
🍅 新增一个歌单
// 用curl模拟一下请求 参数{"name":"夜曲","cover":"xxxx"}
curl localhost:3000/api/music/playlists -X POST -d '{"name":"夜曲","cover":"xxxx"}' -H 'Content-Type: application/json'
🍅 修改一个歌单
curl localhost:3000/api/music/playlists/101 -X PUT -d '{"id":101,"name":"月半小夜曲","cover":"xxxx"}' -H 'Content-Type: application/json'
🍅 删除一个歌单
curl localhost:3000/api/music/playlists/101 -X DELETE -H 'Content-Type: application/json'
以上也可以用postman模拟请求
#给所有的响应头添加header
新建middleware.js
json-server index.js --routes routes.json --middleware middleware.js
8.8 Stream 手机抓包APP
安装软件-> 安装证书-> 信任证书