日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

接口拦截及数据模拟方案:Mock.js

發布時間:2023/12/8 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 接口拦截及数据模拟方案:Mock.js 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Mock.js

以下任何示例界面已部署,大家可點擊使用,地址如下:mock轉換演示地址

注意:mock.js在接收文件流時,會攔截轉換,導致請求返回的文件流數據異常,無法轉為正確的文件,需要關閉才可以

什么是Mock.js

在我們開發中,經常能碰見這樣的問題:前端開發的進度快于后端接口的開發,這種情況之下,前端通常只能等待后端接口開發完畢或者依據后端提供的接口文檔將數據在代碼中寫死,前者會浪費前端大量人力,而第二種會很麻煩(少量數據還勉強能造出來,但是需要較多的數據測試的話,尤其是造一些非文本類數據會特別麻煩),因此 MockJs 就是為了優化這一流程而出現的。

那 MockJs 到底是干什么的呢?

官網首頁已經說的很清楚明了:生成隨機數據,攔截 Ajax 請求。也就是說,它類似于代理工具,當前我們的代理工具有很多,基于瀏覽器插件的有 Proxy SwitchOmega,獨立以軟件存在的有 Fiddler 、Rythem 等,這些都能夠滿足上述的需求,那 MockJs 有什么優點呢?我們將會通過構建一個嵌入 MockJs 項目來一起了解這個工具。

規則了解

在實際操作之前,我們需要對 MockJs 數據生成規則做一些了解,整體來說,MockJs 整體生成數據的規則都是使用表達式模式,輸入指定表達式,通過 Mock.mock 方法就可以生成相對應的數據。

表達式結構分為數據key、數據規則及基礎數據三個模塊,數據key代表生成數據后的key值,數據規則代表數據生成的規則,基礎數據作用與生成規則有關,部分規則需要與基礎數據結合共同表達,例如:"string|3": "★★★" 數據key為 string ,規則為生成 ★★★ 三次,最后生成結果為:{string: "★★★★★★★★★"} ,而如果規則不需要與基礎數據結合共同表達,則基礎數據的作用就剩下了表表明數據類型的作用,例如:"number|1-100": 100 此時我們需要生成一個 1 - 100 的數字,100 告訴的 mock 這個數據類型是Number 類型的,具體的數據規則如下:

常見數據類型操作有三種:分別是范圍 1-10 、 遞增 +1 、常量重復或對象隨機抽取 3

作用范式示例生成數據
字符串隨機重復key|數字范圍: 字符串“String|1-10”: "Mock "{ String: 'Mock Mock Mock Mock Mock Mock ’ }
字符串重復key|數字: 字符串“String|2”: "Mock "{ String: 'Mock Mock ’ }
數字遞增key|+數字: 數字‘rows|2’: [{‘id|+1’: 0,}][ {“id”: 0},{“id”: 1} ]
隨機整數key| 數字范圍: 數字“number|1-100”: 100{ “number”: 64 }
隨機非整數key|數字范圍.精確度范圍: 數字“random|1-100.1-10”: 1{ “random”: 14.24846 }
隨機布爾值key|1: 布爾值“boolean|1”: true{ “boolean”: false }
固定數量隨機枚舉key|數字: 對象列表“object|1”: { “310000”: “上海市”, “320000”: “江蘇省”, “330000”: “浙江省” }“object”: { “310000”: “上海市” }
隨機數量隨機枚舉key|數字范圍: 對象列表“object|1-3”: { “110000”: “北京市”, “120000”: “天津市”, “130000”: “河北省” }“object”: { “120000”: “天津市”, “130000”: “河北省” }
數組內隨機取數據key|數字: 數組“array|1”: [ “AMD”, “CMD”, “UMD” ]{ “array”: “AMD” }
數組內遞增取數據key|+數字: 數組“array|+1”: [ “AMD”, “CMD”, “UMD” ]{ “array”: “UMD” }
隨機長度數組key|數字范圍: 數組‘array|2-5’: [‘array’]{ “array”: [‘array’, ‘array’, ‘array’] }
隨機長度對象數組key|數字范圍: 對象數組‘array|2-5’: [{‘obj’: 1}]{ “array”: [{obj: 1}, {obj: 1}] }
函數處理{值定義, 處理函數定義}{ ‘foo’: ‘Syntax Demo’,
‘name’: function() { return this.foo + 111 } }
{ “foo”: “Syntax Demo”, “name”: “Syntax Demo111” }
正則生成數據key: 正則‘regexp’: /\w\W\s\S\d\D/{ “regexp”: “w@\rs2|” }
變量使用{變量聲明, @變量}{“foo”: “Hello”, “nested”: { “a”: { “b”: { “c”: “Mock.js” } } }, “absolutePath”: “@/foo @/nested/a/b/c”}{ “foo”: “Hello”, “nested”: {“a”: {“b”: {“c”: “Mock.js” }}},“absolutePath”: “Hello Mock.js” }
隨機整數key: @integer( 最小, 最大 )random: ‘@integer(1, 9)’{random: 2}
隨機字符key: @character(字符描述)character: ‘@character(“upper”)’{character: ‘N’}
隨機字符串key: @string(字符描述, 長度)string: ‘@string(“lower”, 5)’{string: ‘lvyki’}
范圍內數字數組key: @range(開始值,結束值,跳躍值)array: ‘@range(1, 10, 3)’{ array: [1, 4, 7] }
隨機日期key: @date(格式)date: ‘@date(“yyyyMMdd”)’{date: ‘20030515’}

以下方法主要生成常見或者有固定規則的數據

作用范式示例生成數據
隨機id@idid: ‘@id’{ id: “360000199504157347” }
生成guid@guidguid: ‘@guid’{ guid: “D2f1158d-B413-BF71-eFe9-52EBBbA7BAae” }
全局自增長數字@increment(跨度)increment: ‘@increment(100)’{ increment: 103}
圖片生成連接Random.image()Random.image()‘http://dummyimage.com/240x400’
圖片base64Random.dataImage()Random.dataImage()
隨機16進制顏色@colorcolor: ‘@color’{color: ‘#f279a6’}
大量英文文本@paragraphparagraph: ‘’@paragraph’’
大量中文文本@cparagraphcparagraph: ‘’@cparagraph’’
模擬域名@urlurl: ‘’@url’{ url: “http://ljjtwm.fi/bzxpdy” }
模擬email@emailemail: ‘@email’{ email: “y.aikj@ped.mobi”}
模擬IP地址@ipip: ‘@ip’{ ip: “211.214.230.62”}
模擬地域@regionregion: ‘@region’{ region: “西北” }
省份@provinceprovince: ‘@province’{ province: “廣西壯族自治區” }
市級@city(是否前綴)city: ‘@city(true)’{ city: “上海 上海市” }
縣級@county(是否前綴)county: ‘@county(true)’{ county: “廣西壯族自治區 南寧市 良慶區” }

以下方法主要適合其他需求的工具

作用范式示例生成數據
首字母大寫@capitalize(英文)hello: ‘@capitalize(“hello”)’{ hello: “Hello” }
全部大寫@upper(英文)upper: ‘@upper(“hello”)’{ upper: “HELLO” }
全部小寫@lower(英文)hello: ‘@lower(“HELLO”)’{ hello: “hello” }
數組洗牌@shuffle(數組)array: ‘@shuffle([“a”, “e”, “i”, “o”, “u”])’{ array: [“e”,“i”,“a”,“u”,“o”] }

MockJs使用

首先,我們需要準備一套前端框架,在這里我使用腳手架生成一個 vue 框架,具體生成流程請參照 Vue2.0 搭建Vue腳手架(vue-cli)

項目使用 element 組件,需要提前配置,在此不做描述

下面給出的例子都將上傳至 git上,地址將在文章最后給出,大家如果需要源碼可自取

安裝 mockjs :

npm install mockjs

后面涉及到代碼編輯及 ajax 請求,所以安裝一個代碼編輯組件及 axios :

npm install codemirror npm install axios

初級使用:通過方法生成數據

首先我們要介紹的是 mockjs 的最基礎用法:使用 Mock.mock 方式生成單條模擬數據,在接口文檔確定的情況下,我們可以使用 mockjs 去模擬生成與文檔預期相同的對象,這種使用方法適合表格類或信息展示類界面,能夠快速輕便的生成符合預期的界面填充數據。

為了展示這個功能,我們搭建一個界面:首先,我們搭建一個界面,界面結構分為三塊:頭部展示描述信息、左側放置可編輯 mock 范式的編輯器、右側放置生成的數據。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TzdDd8kl-1638797452721)(.\img\page1.bmp)]

架構代碼如下:

<template><div class="container"><el-page-header @back="goBack" content="初級使用"></el-page-header><div class="title">mock初級使用方式為Mock函數的使用,我們通過調用Mock.mock方法及自帶屬性,生成想要的數據</div><div class="title bold">key值請用引號包裹</div><div class="title bold">最后一個對象及數組后面請勿添加,否則會報錯</div><el-divider></el-divider><div class="box-container"><div class="code"><textarea ref="textarea"></textarea><el-button class="format" @click="format">格式化</el-button></div><el-button class="button" @click="transfer">生成</el-button><div class="reslut"><textarea ref="showText"></textarea></div></div></div> </template><style scoped lang="less"> .container {.title {text-align: center;}.bold {font-weight: 800;color: red;}span {margin: 0 auto;}.box-container {display: flex;align-items: center;div {height: 300px;display: inline-block;}.button {height: 40px;margin: 0 5px;}.code {flex: 1;width: 40%;}.operation {width: 15%;}.reslut {flex: 1;width: 40%;border: 1px solid #DCDFE6;overflow: auto;}} } </style>

引入 codemirror 代碼展示器、 mockjs 、axios :

import _CodeMirror from 'codemirror' // 核心樣式 import 'codemirror/lib/codemirror.css' // 引入主題后還需要在 options 中指定主題才會生效 import 'codemirror/theme/cobalt.css' import 'codemirror/mode/javascript/javascript.js' import Mock from 'mockjs' // 嘗試獲取全局實例 const CodeMirror = window.CodeMirror || _CodeMirror

mounted 構建時初始化兩個編輯器

// 初始化編輯器實例,傳入需要被實例化的文本域對象和默認配置 this.coder = CodeMirror.fromTextArea(this.$refs.textarea, this.options) // 編輯器賦值 this.coder.setValue(this.code) // 支持雙向綁定 this.coder.on('change', (coder) => {this.code = coder.getValue() })// 初始化編輯器實例,傳入需要被實例化的文本域對象和默認配置 this.coderShow = CodeMirror.fromTextArea(this.$refs.showText, {...this.options, readOnly: 'nocursor'})

此時界面如圖所示:

左邊編輯器為范式輸入內容,點擊生成可在右側生成相應結果

生成功能就用到了我們的 MockJs 了,代碼如下:

transfer () {// 將所有單引號變為雙引號,去除文本中的換行let codeDouble = this.code.replace(/'/g, '"')codeDouble = codeDouble.replace(/\/ +/g, '')codeDouble = codeDouble.replace(/[\r\n]/g, '')try {// 將文本轉化為對象并使用Mock.mock生成結果let code = JSON.parse(codeDouble)this.resultCode = Mock.mock(code)// 將結果做多次轉換之后放入展示編輯器內let resStr = JSON.stringify(this.resultCode)this.coderShow.setValue(JSON.stringify(JSON.parse(resStr), null, 4))} catch (error) {// 當解析失敗時,彈出彈窗提示this.$message({message: '解析失敗,請檢查代碼是否符合規范',type: 'warning'})} },

在我們點擊生成事件之后,去除左側編輯器內內容并將其轉化為較規范的字符串,再將其轉化為可用于生成數據的對象,最后放入右側的展示編輯器中(注:放入編輯器之前為什么要將數據在對象與字符串來回的轉化,因為 MockJs 生成的數據是沒有換行和縮進格式的數據,如果直接賦值,會導致生成的數據擠到一起,很不美觀,所以我們通過這種方式將其展示標準化)

最后我們實現的效果如圖所示:

進階使用:攔截請求模擬數據

上面有講到我們如何在開發時使用 MockJs 去生成需要的模擬數據,但是比較麻煩的事,這樣生成代碼模擬不出來請求返回的效果(因為請求是異步的,有可能會引起一些錯誤的交互邏輯),那有什么辦法將數據模擬成請求的方式呢?

那么就得提到 Mock.mock 另一個使用方式了,那就是請求攔截,使用方式大致為:

Mock.mock(接口或正則, 請求類型, Mock范式)

為了表現其功能,我們通過例子的方法去展示其特性:

界面風格與上一個類似,我們左邊設置需要攔截的請求,包括請求的 url 、請求方法以及模擬數據格式,右側可以輸入相應的請求,點擊發送即可看到攔截返回的數據,話不多說,先上界面結構的代碼:

<template><div class="container"><el-page-header @back="goBack" content="進階應用"></el-page-header><div class="title">mock中進階應用方式為:通過MockJs的方法攔截請求,并返回構建的假數據</div><div class="title bold">key值請用引號包裹</div><div class="title bold">最后一個對象及數組后面請勿添加,否則會報錯</div><el-divider></el-divider><div class="container-body"><div class="box-container"><div class="title">攔截請求</div><div class="show-box"><el-input class="url" placeholder="請輸入攔截請求" v-model="interceptUrl" @change="interceptChange"><template slot="prepend">Http://</template></el-input><el-select class="method" v-model="interceptMethod" @change="interceptChange" placeholder="請選擇"><el-optionv-for="item in methodList":key="item":label="item":value="item"></el-option></el-select><div class="body-title">攔截范式:</div><textarea ref="interceptInput"></textarea></div></div><div class="box-container"><div class="title">發送請求</div><div class="show-box"><el-input class="url send-url" placeholder="請輸入請求" v-model="sendUrl"><template slot="prepend">Http://</template></el-input><el-select class="method" v-model="sendMethod" placeholder="請選擇"><el-optionv-for="item in methodList":key="item":label="item":value="item"></el-option></el-select><el-button type="primary" @click="send">發送</el-button><div class="body-title">返回結果:</div><textarea ref="resultInput"></textarea></div></div></div></div> </template> <style scoped lang="less"> .container {.title {text-align: center;}.bold {font-weight: 800;color: red;}.container-body {margin: 0 auto;.box-container {width: 47%;display: inline-block;padding: 1%;.show-box {padding-top: 10px;.url {width: 89%;}.method {width: 10%;}.body-title {margin: 10px 0px;}.send-url {width: 79%;}.send-button {width: 10%;}}}} } </style>

界面初始化流程就不多說了:

import _CodeMirror from 'codemirror' // 核心樣式 import 'codemirror/lib/codemirror.css' // 引入主題后還需要在 options 中指定主題才會生效 import 'codemirror/theme/cobalt.css' import 'codemirror/mode/javascript/javascript.js' import Mock from 'mockjs' import axios from 'axios'// 嘗試獲取全局實例 const CodeMirror = window.CodeMirror || _CodeMirror

初始化編輯器:

// 初始化編輯器實例,傳入需要被實例化的文本域對象和默認配置 this.interceptCoder = CodeMirror.fromTextArea(this.$refs.interceptInput, this.options) // 編輯器賦值 this.interceptCoder.setValue(this.interceptCode) // 支持雙向綁定 this.interceptCoder.on('change', (coder) => {this.interceptCode = coder.getValue()// 每一次改變重新配置攔截this.interceptChange() })// 初始化編輯器實例,傳入需要被實例化的文本域對象和默認配置 this.coderShow = CodeMirror.fromTextArea(this.$refs.resultInput, {...this.options, readOnly: 'nocursor'})

接下來是重點部分,設置攔截及請求發送

// 設置攔截 interceptChange () {// 將所有單引號變為雙引號,去除文本中的換行let codeDouble = this.interceptCode.replace(/'/g, '"')codeDouble = codeDouble.replace(/\/ +/g, '')codeDouble = codeDouble.replace(/[\r\n]/g, '')try {// 將文本轉化為對象并使用Mock.mock攔截請求let code = JSON.parse(codeDouble)Mock.mock(this.interceptUrl, this.interceptMethod, code)this.isTrue = true} catch (error) {this.isTrue = false} }, // 發送請求 send () {if (!this.isTrue) {this.$message({message: '范式解析失敗,請檢查范式是否符合規范',type: 'warning'})} else {axios[this.sendMethod](this.sendUrl, {}).then(res => {// 請求成功時,展示返回結果this.coderShow.setValue(JSON.stringify(res.data, null, 4))}).catch(error => {// 請求失敗時,展示錯誤this.coderShow.setValue(JSON.stringify(error.message, null, 4))})} }

最終結果如下:

當然,為了保障模擬更真實,我們可以設置延遲時間:

Mock.setup({timeout: '200-600', });

高階使用:將攔截變為可配置項

通過上面的例子,我們可以使用 MockJs 去攔截并生成模擬數據,但是這種方法有幾個缺點:

  • 一個界面會有很多請求,界面中要寫很多模擬相關的代碼,導致前期代碼過于臃腫
  • 需要調試的時候,我們又要刪除這些模擬數據代碼,下次需要使用還得造
  • 如果不小心把模擬數據代碼殘留下來,一旦發布出去界面功能將會失效

那么我們高階使用要做的有以下幾點:

  • 模擬代碼單獨隔離
  • 代碼可重復使用
  • 模擬功能可開關
  • 模擬代碼只在開發階段生效

我們的設計如下:我們將攔截信息設置為可配置的對象,將接口信息(請求方式|接口名稱)作為 key 值,mock 范式作為 value 值,結構如下:

'post|/demo': {'name': '@cname' }

在項目初始化的時候我們獲取所有的配置項,并通過 Mock.mock 方法添加攔截,這樣的話我們就做到了第一和第二兩個特點:在開發界面沒有多余代碼,代碼可重復使用,其實現方式如下:

// 代碼結構: // - mockjs // - demo // - demo.js // - index.js // 使用Webpack的require.context()遍歷所有mock文件 const files = require.context('.', true, /\.js$/) files.keys().forEach((key) => {// 剔除配置文件if (key === './index.js') {return}// 將所有配置文件的對象放入數組中configArray = configArray.concat(files(key).default) })// 注冊所有的mock服務 configArray.forEach((item) => {for (const [path, target] of Object.entries(item)) {// 將key拆解為請求方式及攔截路徑,并添加攔截const protocol = path.split('|')Mock.mock(new RegExp('^' + config.rootPath + protocol[1]), protocol[0], target)} })

第三個特點的實現也比較簡單,我們添加一個配置文件 mock.config.js 其中添加開關配置項 enableMock ,在上述代碼中添加一個判斷語句,根據是否打開開關決定是否解析并攔截請求。

那怎么做到只在生產環境生效呢?我們項目初始化后為了區分生產環境與開發環境,在config 文件夾下放置了兩個區分文件,分別是 dev.env.js 與 prod.env.js ,在文件中定義了不同的 NODE_ENV 參數,當我們使用 npm run dev 命令時,系統讀取 dev.env.js 代碼,此時系統變量 process.env.NODE_ENV === ‘development’ 如果我們使用 npm run build 時 process.env.NODE_ENV === ‘production’ ,我們通過這個變量判斷當前環境是否處于開發環境,然后在程序入口 main.js 中添加啟動 mockjs 解析語句:

if (process.env.NODE_ENV === 'development') {require('./mockjs/index') }

這樣一來我們即使在打包時忘了關閉 mock 的開關,也不會影響到生產環境的接口調用,在這里我門也做了一個例子,具體代碼就不展示了,大家想看的話可以去我的 git 下拉取代碼,最后界面如下:

總結

對于 mockjs 的使用,是針對著一些常見的開發現象的,在開發時,我們經常會遇到這種情況:前端早早的開發完畢,但是后端由于業務復雜,暫時提供不了數據,導致前端無法做一些操作代碼正確性驗證,但是通過 mockjs 我們就不必再拘泥于后端數據,我們根據后端提供的接口文檔,就可以配置模擬出想要的數據,這樣我們在假的環境里能夠完整的調試我們的界面邏輯,能夠非常大的減少聯調周期。其次我們有時對于現場的特殊數據導致的前端問題,而后端構建數據困難時,我們也可以使用 mockjs 去模擬這些數據,達到模擬現場環境的效果。

git地址:https://github.com/shiyingjieGra/mockJsWeb

句:

if (process.env.NODE_ENV === 'development') {require('./mockjs/index') }

這樣一來我們即使在打包時忘了關閉 mock 的開關,也不會影響到生產環境的接口調用,在這里我門也做了一個例子,具體代碼就不展示了,大家想看的話可以去我的 git 下拉取代碼,最后界面如下:

總結

對于 mockjs 的使用,是針對著一些常見的開發現象的,在開發時,我們經常會遇到這種情況:前端早早的開發完畢,但是后端由于業務復雜,暫時提供不了數據,導致前端無法做一些操作代碼正確性驗證,但是通過 mockjs 我們就不必再拘泥于后端數據,我們根據后端提供的接口文檔,就可以配置模擬出想要的數據,這樣我們在假的環境里能夠完整的調試我們的界面邏輯,能夠非常大的減少聯調周期。其次我們有時對于現場的特殊數據導致的前端問題,而后端構建數據困難時,我們也可以使用 mockjs 去模擬這些數據,達到模擬現場環境的效果。

git地址:https://github.com/shiyingjieGra/mockJsWeb

總結

以上是生活随笔為你收集整理的接口拦截及数据模拟方案:Mock.js的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。