前后端分离,可以提升开发效率, 增强代码可维护性。前后端分离开发,使用mock来模拟数据
1.使用json-server打造mock server
优秀的mock server应该有的特性:
快速搭建
支持标准的Restful操作
支持标准的Restful路由规则
自定义路由,中间件支持等等。
下面的地址可以查看json-server的相关内容
https://github.com/typicode/json-server
首先在项目里面安装json-server,如下命令,
npm install json-server --save-dev
在项目的根目录下面创建db.json文件,粘贴一下官网上的代码,文件内容如下:
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
然后在package.json文件的scripts字段里面添加下面的代码
"mock": "json-server --watch db.json"
保存之后直接运行命令
npm run mock
看到控制台输出下面内容:
{_}/ hi!
Loading db.json
DoneResources
http://localhost:3000/posts
http://localhost:3000/comments
http://localhost:3000/profileType s + enter at any time to create a snapshot of the database
Watching...
在浏览器中输入 http://localhost:3000/posts 地址打开看一下:可以看到下面的内容,返回了我们定义的数据
[ { "id": 1, "body": "some comment", "postId": 1 } ]
当修改db.json中内容时候,如下所示,打开地址看到的内容也不相同
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" },
{ "id": 2, "title": "json-server-2", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
浏览器中看到返回的信息是这样的
[ { "id": 1, "title": "json-server", "author": "typicode" }, { "id": 2, "title": "json-server-2", "author": "typicode" } ]
http://localhost:3000/posts/1 当我们输入这样的地址时,浏览器中会返回第1条的数据。
第3条中的数据是返回对象的数据。
2.分析和创建Restful接口
根据项目中的应用,更改db.json文件内容,内容如下:
{
"categories": [
{
"name": "旅行",
"iconName": "ios-plane",
"id": "1",
"type": "outcome"
},
{
"name": "其他",
"iconName": "ios-apps",
"id": "15",
"type": "income"
}
],
"items": [
{
"title": "再次更新标题",
"price": 2000,
"date": "2018-09-15",
"monthCategory": "2018-9",
"id": "_qmatbbwq0",
"cid": "6",
"timestamp": 1536969600000
},
{
"title": "新的旅行条目",
"price": 10000,
"date": "2019-01-05",
"monthCategory": "2019-1",
"timestamp": 1546646400000,
"id": "_cg4a9gzya",
"cid": "1"
}
]
}
get 的请求,我们可以直接在浏览中输入地址来判断,那post请求呢?
使用postman测试API接口,官网地址
postman的特点:
支持各种操作系统
有非常简洁易用的界面
可以支持API测试的导出,很容易分享给其他开发
3.Axios
Axios的优点:前后发送请求,获取后台数据
输入下面命令安装axios
npm install axios --save
在react项目中的index.js中引入这个api
import Axios from 'axios'
该项目在运行的时候就要开2个terminal窗口,一个窗口运行
npm run mock
另外一个窗口运行
npm start
发现下面的提示信息,是因为mock server和react的端口撞上了,我们可以给mock修改一个端口
? Something is already running on port 3000.
Would you like to run the app on another port instead? (Y/n)
在package.json文件中修改scripts内容
"mock": "json-server --watch db.json --port 3004"
如果每次都要运行这2个命令启动mock server和react项目,这样比较麻烦,有没有简单一点的办法呢?
通过借助工具concurrently 来实现一条命令运行多条命令,利用npm安装这个工具
npm install concurrently --save -dev
下面的2条命令就变成了一条
"start": "react-scripts start",
"mock": "json-server --watch db.json --port 3004"
如下所示引入axios,获取模拟的接口数据,发现报错了
import React from 'react';
import ReactDOM from 'react-dom';
import TabelBasic from './antd/TabelBasic'
import axios from 'axios';
axios.get('localhost:3004/items').then((response) => {
console.log(response);
});
ReactDOM.render(<TabelBasic /> ,document.getElementById('root'));
serviceWorker.unregister();
Access to XMLHttpRequest at 'localhost:3004/items' from origin 'http://localhost:3000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
:3004/items:1 Failed to load resource: net::ERR_FAILED
createError.js:16 Uncaught (in promise) Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:83)
这个报错是由于跨域导致的错误,2个服务器端口不一致导致的,可以通过添加package.json的文件内容来解决这个问题:
"proxy": "http://localhost:3004"
然后修改index.js内容,重启服务,就正常了。
import React from 'react';
import ReactDOM from 'react-dom';
import TabelBasic from './antd/TabelBasic'
import axios from 'axios';
axios.get('/items').then((response) => {
console.log(response);
});
ReactDOM.render(<TabelBasic /> ,document.getElementById('root'));
serviceWorker.unregister();
浏览器控制台打印下面的内容,说明get请求已经成功了
- data: (13) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
- status: 200
- statusText: "OK"
- headers: {access-control-allow-credentials: "true", cache-control: "no-cache", connection: "close", content-encoding: "gzip", content-type: "application/json; charset=utf-8", …}
- config: {url: "/items", method: "get", headers: {…}, transformRequest: Array(1), transformResponse: Array(1), …}
- request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
如何发送post请求呢?
拷贝一条数据,调用post请求发送方法,如下面的代码:
import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
const newItem={
"title": "再端到端",
"price": 2000,
"date": "2019-09-15",
"monthCategory": "2018-9",
"id": "_qmatbbwq0222",
"cid": "622",
"timestamp": 1536969600000
}
axios.post('/items', newItem).then((response) => {
console.log(response);
})
ReactDOM.render(<TabelBasic /> ,document.getElementById('root'));
serviceWorker.unregister();
结果如下所示:status的数值改变了
{data: {…}, status: 201, statusText: "Created", headers: {…}, config: {…}, …}
data: {title: "再端到端", price: 2000, date: "2019-09-15", monthCategory: "2018-9", id: "_qmatbbwq0222", …}
status: 201
statusText: "Created"
headers: {access-control-allow-credentials: "true", access-control-allow-origin: "http://localhost:3004/", access-control-expose-headers: "Location", cache-control: "no-cache", connection: "close", …}
config: {url: "/items", method: "post", data: "{"title":"再端到端","price":2000,"date":"2019-09-15","…tbbwq0222","cid":"622","timestamp":1536969600000}", headers: {…}, transformRequest: Array(1), …}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
__proto__: Object