在前后端分離的趨勢下,前端開發逐步減少對后端的依賴,甚至可以不與后端進行聯調,獨立交付需求,在這樣的背景下,首先要解決的就是介面資料的Mock,根據服務端約定好的介面進行資料Mock,同時修改資料來滿足不同的開發場景,
一、請求流程介紹
首先來分析下開發環境下請求的整個流程:

發送請求流程:
1. 操作頁面時首先會經過編譯后的原始碼,按照原始碼的邏輯進行請求封裝,再發送請求
2. 請求通過瀏覽器向目標地址發送請求,開發環境下目標地址為編譯工具提供的前端服務器地址
3. 編譯工具接收到請求后,根據配置項對請求處理,處理完成后向后端服務器發送請求
回應請求流程:
1. 后端服務器接收請求后,匹配到對應的路由進行邏輯處理,并將結果回傳
2. 編譯工具拿到結果,根據配置項內容進行處理,向瀏覽器回傳處理后的結果
3. 瀏覽器接收資料后,按照原始碼邏輯處理資料,將新的資料呈現在頁面上
二、Mock解決方案
按照請求在本地和服務器兩端控制,我們將Mock方式分為本地Mock和服務器Mock:

根據上述請求的整個流程,前端Mock資料的解決方案可以大致分為以下幾種:
1. 本地Mock
1.1 邏輯嵌入
1.2 原始碼請求攔截
1.3 瀏覽器請求攔截
1.4 代理封裝
2. 服務器Mock
2.1 服務化
2.2 代理攔截
2.3 服務攔截
我們以渲染一個串列為例,使用Axios獲取介面資料:
// userlist.js 檔案
import axios from 'axios'
const getUserList = async () => {
const users = await axios.get('/user/list')
return users.data.responseData
}
三、Mock方案實踐
一. 本地Mock
方式一:邏輯嵌入
最簡單一個方式就是將資料直接回傳,不發送請求,

// mock.js
export default users = {
status: 200,
data: {
responseData: [{
name: 'user1'
}],
err: null
}
}
// userlist.js 檔案
import axios from 'axios'
import usersData from 'mock.js'
const getUserList = async () => {
// const users = await axios.get('/user/list')
const users = usersData
return users.data.responseData
}
結論:
優點: 前端控制介面資料,不必通過后端增刪改來修改回傳資料;
缺點: 這種方式侵入到了代碼中,開發和后期維護肯定是極其不友好的;
方式二:原始碼請求攔截
使用中間件,統一在中間件做處理,axios提供了攔截器,可以在回應的攔截器中做統一的處理,
(不只是axios,其他的請求工具也都提供了攔截器的功能,這里主要說明解決方案)

// axiosConfig.js組態檔
import usersData from 'mock.js'
import axios from 'axios'
axios.interceptors.response.use((response) => {
if (response.request.url === '/user/list') {
return usersData;
}
return response
}, (error) => {
return Promise.reject(error);
});
export default axios
// userlist.js 檔案
import axios from 'axiosConfig'
const getUserList = async () => {
const users = await axios.get('/user/list')
return users.data.responseData
}
結論:
優點: 這種方式與上一個相比,統一在一個檔案內管理,減少了對業務代碼的侵入;
缺點: 同樣的還是有代碼的侵入;
方式三:瀏覽器請求攔截
攔截請求,請求直接在瀏覽器里回傳結果,使用Service Worker對請求進行出來,回傳自定義結果,比如 Mock Service Work工具

import { rest, setupWorker } from 'msw'
import userData from 'mock.js'
const handlers = [
rest.get('/user', () => {
return res(
ctx.status(200),
ctx.json(userData)
)
})
]
const worker = setupWorker(...handlers)
if (process.env.NODE_ENV === 'development') {
worker.start()
}
結論:
優點:統一在一個檔案內管理,較少對代碼的侵入;
缺點:在專案內還是會有侵入,資料修改不靈活;
方式四:代理封裝
使用打包工具的本地服務功能轉發請求,在開發環境下,都會起一個服務,用于本地訪問查看頁面,基于這個流程,可以在服務上做一些處理,
(以webpack工具為例,在代理配置中添加路由,并在該路由下修改回傳物件,)

// webpack.dev.js
module.exports = {
//...
devServer: {
proxy: {
'/user': {
target: 'http://localhost:3000',
bypass: function (req, res, proxyOptions) {
// 需要轉換 mock.js 為 json檔案,webpack在node環境下不支持import方式
let jsonPath = path.resolve(__dirname, 'mock.json')
res.status(200).send( JSON.parse( fs.readFileSync(jsonPath) ) )
}
}
}
}
};
以webpack工具為例,在代理配置中添加路由,并在該路由下修改回傳物件,
結論:
優點:使用代理轉發的方式,無代碼侵入,一種全新的思路,是質的提升;
缺點:需要在本地生成多個json檔案,統一個介面,增刪改查都需要配置不同的json檔案;
二. 服務器Mock
繼上面本地轉發的方案后,可以將json檔案抽離到專案之外,開啟一個服務器將json暴露出去,由本地轉發替換為轉發到服務器上,
基于這樣的方案,可以使用資料庫進行存盤代替json檔案,越來越多的Mock平臺出現了,比如 大搜車的easymock、阿里的 rap2、去哪兒網的 Yapi平臺等等,Yapi介面管理工具不只是前端工具,也集成了測驗方案,是很優秀的工具,
方式一:服務化
打包工具轉發,通過配置代理地址,直接請求到平臺的介面,
首先在平臺上注冊賬戶并添加自己的介面,然后在代理中配置地址,
(以webpack工具為例,在代理配置中添加路由,配置該路由的轉發地址,)

// webpack.dev.js
module.exports = {
//...
devServer: {
proxy: {
'/user': {
target: 'http://xxx.xxx.com/xxx' // 根據平臺地址填寫
}
}
}
};
結論:
優點:介面資料可在平臺實時修改,專案無其他非相關的代碼;
缺點:每次介面修改,都需要重啟服務,修改成本較高;
方式二:代理攔截
使用代理服務器進行轉發,脫離對框架的依賴,在打包工具訪問平臺的網路鏈路流程中,添加一個代理服務器,控制代理服務器從而控制API轉發流程,
(以nginx工具為例,配置不同路由對應的服務器,)

# nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 8081;
server_name 127.0.0.1;
root D:/worksapce/project;
location /user {
# 根據平臺地址填寫
proxy_pass http://xxx.xxx.com/xxx;
}
}
}
// webpack.dev.js
module.exports = {
//...
devServer: {
proxy: {
'/user': {
target: 'http://127.0.0.1:8081'
}
}
}
};
結論:
優點:介面在代理服務器控制,可隨時切換Mock平臺,API地址,解決跨域等問題,不必重啟打包工具;
缺點:需要安裝學習nginx工具,在臨時處理問題等一些特殊場景下成本較高;
方式三:服務攔截
使用后端服務轉發,后端服務不僅可以開發前端介面,回傳需要的資料外,還可以進行路由轉發,回傳對應服務器的介面資料,

// proxy.js 檔案
const http = require('http')
const httpProxy = require('http-proxy')
// 創建一個代理服務
const proxy = httpProxy.createProxyServer();
//創建http服務器并監聽8888埠
let server = http.createServer(function (req, res) {
let url = req.url
if (url.indexOf('/user') >-1) {
//將用戶的請求轉發到本地9999埠上
proxy.web(req, res, () => {
return {
target: 'http://xxx.xxx.com/xxx;', // 根據平臺地址填寫
}
});
//監聽代理服務錯誤
proxy.on('error', function (err) {
console.log(err);
});
}
});
server.listen(8081, '0.0.0.0');
// webpack.dev.js
module.exports = {
//...
devServer: {
proxy: {
'/user': {
target: 'http://127.0.0.1:8081'
}
}
}
};
結論:
優點:快速搭建代理服務,前端友好的Node環境可減低開發難度,代理服務重啟成本低;
缺點:需要多啟動一個代理服務進行轉發;
四、Mock方案總結
本篇文章主要是對Mock資料方案的歸納整理,列舉了簡要的操作步驟,詳細步驟可自行查找相關資料,
結合上面的解決方案,可以根據場景的需要選擇不同的方案:
1. 臨時頁面修改,可通過代碼侵入的方式快速解決;
2. 對應新的專案,可以使用代理服務的方式規范開發;
3. 處理多個專案時,可以通過nginx配置多個埠來降低服務重啟的成本,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293570.html
標籤:其他
