大庆市网站建设_网站建设公司_外包开发_seo优化
2025/12/23 15:38:48 网站建设 项目流程


Mockjs巧解:GET-POST参数差异返回不同数据的实战妙招

  • Mockjs巧解:GET-POST参数差异返回不同数据的实战妙招
    • 前言:后端没好,前端先“演”
    • GET 和 POST 在 Mockjs 眼里到底差在哪?
    • Mockjs 识别请求的“黑话”解析
    • 精准拦截:正则 + method 双保险
    • 实战演练:登录 + 用户信息一条龙
      • 1. 先写工具函数:common.js
      • 2. 用户模块:user.js
      • 3. 统一入口:mock/index.js
      • 4. 在 main.js 里引入
      • 5. 业务层 api/user.js
      • 6. 页面里爽一把
    • 踩坑实录:POST 参数又双叒叕拿不到?
    • 调试技巧:三行代码定位“规则未命中”
    • 进阶玩法:Random 函数让假数据更像真的
    • 让规则更聪明:封装通用 Mock 配置
    • 多人协作:Mock 规范怎么定?
    • 小彩蛋:把 Mockjs 塞进 Vite 的 devServer
    • 结语:Mock 是手段,不是目的

Mockjs巧解:GET-POST参数差异返回不同数据的实战妙招

——“后端影子都没见到,接口却已经跑了两周”是一种怎样的体验?

温馨提示:本文代码量巨大,建议先收藏、后泡咖啡、再撸猫,最后慢慢品读。
如果你正在地铁里刷手机,那就先看完段子,回家再抄代码——反正地铁里也跑不起来npm run dev


前言:后端没好,前端先“演”

故事的开头千篇一律:
周一早上,产品经理拍着你肩膀说,“登录和用户详情页这周五要提测”。
你点点头,打开钉钉,后端老哥头像灰得跟用了十年的机械硬盘一样——请假陪老婆产检去了。
留你一个人对着接口文档发呆,仿佛爱情公寓里曾小贤面对一冰箱的泡面:饿不死,但也吃不好。

这时候,Mockjs 就像楼下新开的那家 24h 便利店:
不是米其林,却能在深夜给你一碗热腾腾的关东煮。
它让前端先行“自嗨”,让页面提前跑通,让测试小姐姐提前点点点,让产品老板提前“哇塞”。
但 Mockjs 也不是慈善家,GET 和 POST 在它眼里并不是“众生平等”。
想用同一套规则糊弄两种请求?
对不起,Mockjs 会翻白眼:“你当我傻?”


GET 和 POST 在 Mockjs 眼里到底差在哪?

先放结论:
Mockjs 只认两件事——URL 是否命中,拦截函数里能不能拿到你想要的参数。
GET 的参数挂在url尾巴上,Mockjs 直接丢到url里让你自己抠;
POST 的参数藏在body里,Mockjs 把body原封不动塞给你,但——
它不会帮你解析!
对,它就是那种“快递送到门口,不帮你拆包装”的冷酷小哥。

所以,“拿到参数”这一步,GET 像剥橘子,POST 像开榴莲——
前者上手就能吃,后者你得先找刀。


Mockjs 识别请求的“黑话”解析

Mockjs 的拦截器长这样:

Mock.mock(RegExp|String,String method,Function(options))

重点在第三个参数options——它把本次请求的所有“零碎”都塞了进来:

字段名说明
url完整地址,带 query
type小写 method:get、post、put…
body仅 POST/PUT 等,字符串,需自行 parse

举个例子,你发了一个:

POST /api/login Content-Type: application/json {"username":"admin","pwd":"123456"}

Mockjs 收到的options长这样:

{url:"/api/login",type:"post",body:'{"username":"admin","pwd":"123456"}'// 注意是字符串!}

想拿 username?
你得自己JSON.parse(options.body).username,否则就是undefined界的老朋友。


精准拦截:正则 + method 双保险

很多同学图省事直接写死地址:

Mock.mock("/api/user","get",{name:"@cname"})

看起来岁月静好,其实一碰就碎:
只要 URL 后面多拼一个时间戳/api/user?_t=123,规则立马失效。
正确姿势是用正则,把时间戳、随机数、哈希全都当成空气:

// 拦截任何以 /api/user 开头的 GET 请求Mock.mock(RegExp("/api/user.*"),"get",function(options){// 解析 query 参数consturlObj=newURL(options.url,location.origin)constuserId=urlObj.searchParams.get("id")return{id:userId,name:Mock.Random.cname(),avatar:Mock.Random.image("200x200",Mock.Random.color(),"#fff","Avatar")}})

POST 同理,只是多一步JSON.parse

Mock.mock(RegExp("/api/login.*"),"post",function(options){const{username,pwd}=JSON.parse(options.body)if(username==="admin"&&pwd==="123456"){return{code:200,token:Mock.Random.guid(),refresh:Mock.Random.guid()}}else{return{code:403,msg:"账号或密码错误,别再瞎猜了"}}})

实战演练:登录 + 用户信息一条龙

光说不练假把式,直接上完整工程级代码。
目录结构先摆好:

src/ ├── mock/ │ ├── index.js // 统一入口 │ ├── modules/ │ │ ├── user.js // 用户相关 │ │ └── common.js // 通用工具 ├── api/ │ ├── user.js // 业务层封装 ├── utils/ │ └── request.js // axios 实例

1. 先写工具函数:common.js

// src/mock/modules/common.jsexportconstparseQuery=(url)=>{const[,search=""]=url.split("?")constparams={}search.split("&").forEach(item=>{const[k,v]=item.split("=")if(k)params[decodeURIComponent(k)]=decodeURIComponent(v||"")})returnparams}exportconstparseBody=(body)=>{try{returnJSON.parse(body)}catch{return{}}}

2. 用户模块:user.js

// src/mock/modules/user.jsimportMockfrom"mockjs"import{parseQuery,parseBody}from"./common"// 模拟数据库constuserDB=[{id:"1001",username:"admin",pwd:"123456",name:"陈北枳",role:"admin"},{id:"1002",username:"editor",pwd:"666666",name:"顾南衣",role:"editor"}]// 登录 POSTMock.mock(RegExp("/api/user/login.*"),"post",(options)=>{const{username,pwd}=parseBody(options.body)constuser=userDB.find(u=>u.username===username&&u.pwd===pwd)if(!user){return{code:403,msg:"用户名或密码错误"}}return{code:200,data:{token:Mock.Random.guid(),refreshToken:Mock.Random.guid(),user:{id:user.id,username:user.username,name:user.name,role:user.role}}}})// 查询用户 GETMock.mock(RegExp("/api/user/info.*"),"get",(options)=>{const{id}=parseQuery(options.url)constuser=userDB.find(u=>u.id===id)if(!user){return{code:404,msg:"用户不存在"}}return{code:200,data:{id:user.id,name:user.name,role:user.role,avatar:Mock.Random.image("200x200",Mock.Random.hex(),"#fff",user.name.slice(-1)),profile:Mock.Random.paragraph(2,5),lastLogin:Mock.Random.datetime("yyyy-MM-dd HH:mm:ss")}}})

3. 统一入口:mock/index.js

// src/mock/index.jsimportMockfrom"mockjs"import"./modules/user"// 环境判断,防止打包到生产if(import.meta.env.DEV){Mock.setup({timeout:"300-800"})// 模拟网络抖动console.log("[Mock] mock 数据已就绪,尽情玩耍吧~")}

4. 在 main.js 里引入

import{createApp}from"vue"importAppfrom"./App.vue"import"@/mock"// 只需这一行,Mock 就生效createApp(App).mount("#app")

5. 业务层 api/user.js

// src/api/user.jsimportrequestfrom"@/utils/request"exportfunctionlogin(data){returnrequest({url:"/api/user/login",method:"post",data})}exportfunctiongetUserInfo(id){returnrequest({url:"/api/user/info",method:"get",params:{id}})}

6. 页面里爽一把

<template> <button @click="handleLogin">一键登录</button> <div v-if="user.name"> <img :src="user.avatar" /> <p>Hi,{{ user.name }},上次登录:{{ user.lastLogin }}</p> </div> </template> <script setup> import { login, getUserInfo } from "@/api/user" import { reactive } from "vue" const user = reactive({}) async function handleLogin() { const { data: loginData } = await login({ username: "admin", pwd: "123456" }) const { data: info } = await getUserInfo(loginData.user.id) Object.assign(user, info) } </script>

运行效果:
点击按钮 → 弹出“Hi,陈北枳,上次登录:2025-12-20 16:38:22”——
全程零后端,老板直呼内行。


踩坑实录:POST 参数又双叒叕拿不到?

  1. Content-Type 没对上
    Mockjs 只认application/json,你发multipart/form-data试试?
    body直接给你一串------WebKitFormBoundary...JSON.parse当场崩溃。

  2. JSON.parse 没 try catch
    一旦前端多传了个 undefined,控制台立刻飘红,整个拦截器罢工。

  3. 正则写太死
    RegExp("/api/user/login")写成了字符串"/api/user/login"——
    恭喜,时间戳一来规则原地去世,调试两小时,发现少写了个.*

  4. Mock.setup 忘记调
    结果拦截器生效了,却每次返回都 0ms,测试小姐姐以为你接口开挂,
    把锅甩给网络,其实是你没加延迟演技


调试技巧:三行代码定位“规则未命中”

// 在 mock/index.js 顶部打开调试开关Mock.mock(RegExp(".*"),".*",function(options){console.log("[Mock Debug]",options.type.toUpperCase(),options.url)returnnull// 返回 null 代表放行,让请求继续走到真实接口})

刷新页面,看控制台:
[Mock Debug] GET /api/user/info?id=1001
如果没打印,说明正则没匹配上;
如果打印了却没走你的规则,说明 method 写错或顺序被覆盖。
定位问题,一杯茶工夫。


进阶玩法:Random 函数让假数据更像真的

Mockjs 内置 50+ 随机函数,举几个我常用的:

Mock.Random.extend({status(){// 自定义业务状态returnthis.pick(["active","inactive","pending"])},ip(){// 随机内网 ipreturn`192.168.${this.natural(0,255)}.${this.natural(1,254)}`}})// 使用constrecord=Mock.mock({id:"@guid",ip:"@ip",status:"@status",createdAt:"@datetime",detail:{cpu:"@natural(20, 90)%",memory:"@natural(30, 80)%",disk:"@natural(40, 95)%"}})

再配合Mock.Random.image生成带随机文字的占位图,
测试小姐姐再也不会拿“数据太假”来怼你。


让规则更聪明:封装通用 Mock 配置

项目一大,mock 文件几十上百个,
每个都写一遍Mock.mock(RegExp(...), "get", ...)迟早崩溃。
函数式封装了解一下:

// src/mock/createMock.jsimportMockfrom"mockjs"exportfunctioncreateMock({url,method,response}){constreg=typeofurl==="string"?RegExp(`${url}.*`):url Mock.mock(reg,method.toLowerCase(),function(options){constdata=typeofresponse==="function"?response(options):responsereturn{code:200,data}})}

调用姿势:

import{createMock}from"@/mock/createMock"createMock({url:"/api/list",method:"get",response:()=>Mock.mock({"list|10-20":[{id:"@id",title:"@ctitle"}]})})

一行代码一个接口,后续统一加延迟、加日志、加拦截,都在createMock里改,
多人协作不再鸡飞狗跳。


多人协作:Mock 规范怎么定?

  1. 统一目录:按业务模块划分子目录,拒绝“一个文件 2000 行”。
  2. 统一命名模块.method.api.js,例如user.get.info.js
  3. 统一入口mock/index.js只负责批量import,不写具体规则。
  4. 统一数据工厂:把Random扩展、公共模板放到mock/factory
    谁要用谁引用,避免“同一个手机号 8 个人写了 8 遍”
  5. Git 提交加钩子pre-commit里跑eslint + mock-json-validator
    防止把非法 JSON 传上去,半夜三点报警把你吓醒

小彩蛋:把 Mockjs 塞进 Vite 的 devServer

Vite 官方已经支持configureServer,可以彻底抛弃mockjs前端拦截,
直接在 devServer 层返回 mock 数据,连浏览器都感知不到:

// vite.config.jsimport{defineConfig}from"vite"import{createMock}from"./mock/back-mock"// 自己写的 node 层 mockexportdefaultdefineConfig({plugins:[vue()],server:{port:3000,proxy:{"/api":{target:"http://localhost:3000",changeOrigin:true,configure:(proxy,options)=>{createMock(proxy,options)// 把 mock 挂在 proxy 上}}}}})

createMock内部用express写中间件,
请求根本没出 Node,却被伪装成真实接口
抓包工具都看不出来,测试小姐姐直呼“这接口真快”


结语:Mock 是手段,不是目的

Mockjs 再香,也别忘了它的使命——让前端先行,让联调不慌
项目后期,务必安排“去 Mock”战役
把规则文件统一迁移到mock-archive分支,
把真实接口地址挨个替换,
console.log里的[Mock]全部干掉。

否则,上线后用户看到一屏幕 Random.guid(),
就不是“接口真香”,而是“年终绩效不保”。

愿你在每一个后端迟到的清晨,
都能用一杯咖啡 + 一段 Mock 规则,
换来测试小姐姐的微微一笑,
以及产品经理那句——

“欸?接口这么快就通了,后端不是说下周吗?

欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

推荐:DTcode7的博客首页。
一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身农奴把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟!


专栏系列(点击解锁)学习路线(点击解锁)知识定位
《微信小程序相关博客》持续更新中~结合微信官方原生框架、uniapp等小程序框架,记录请求、封装、tabbar、UI组件的学习记录和使用技巧等
《AIGC相关博客》持续更新中~AIGC、AI生产力工具的介绍,例如stable diffusion这种的AI绘画工具安装、使用、技巧等总结
《HTML网站开发相关》《前端基础入门三大核心之html相关博客》前端基础入门三大核心之html板块的内容,入坑前端或者辅助学习的必看知识
《前端基础入门三大核心之JS相关博客》前端JS是JavaScript语言在网页开发中的应用,负责实现交互效果和动态内容。它与HTML和CSS并称前端三剑客,共同构建用户界面。
通过操作DOM元素、响应事件、发起网络请求等,JS使页面能够响应用户行为,实现数据动态展示和页面流畅跳转,是现代Web开发的核心
《前端基础入门三大核心之CSS相关博客》介绍前端开发中遇到的CSS疑问和各种奇妙的CSS语法,同时收集精美的CSS效果代码,用来丰富你的web网页
《canvas绘图相关博客》Canvas是HTML5中用于绘制图形的元素,通过JavaScript及其提供的绘图API,开发者可以在网页上绘制出各种复杂的图形、动画和图像效果。Canvas提供了高度的灵活性和控制力,使得前端绘图技术更加丰富和多样化
《Vue实战相关博客》持续更新中~详细总结了常用UI库elementUI的使用技巧以及Vue的学习之旅
《python相关博客》持续更新中~Python,简洁易学的编程语言,强大到足以应对各种应用场景,是编程新手的理想选择,也是专业人士的得力工具
《sql数据库相关博客》持续更新中~SQL数据库:高效管理数据的利器,学会SQL,轻松驾驭结构化数据,解锁数据分析与挖掘的无限可能
《算法系列相关博客》持续更新中~算法与数据结构学习总结,通过JS来编写处理复杂有趣的算法问题,提升你的技术思维
《IT信息技术相关博客》持续更新中~作为信息化人员所需要掌握的底层技术,涉及软件开发、网络建设、系统维护等领域的知识
《信息化人员基础技能知识相关博客》无论你是开发、产品、实施、经理,只要是从事信息化相关行业的人员,都应该掌握这些信息化的基础知识,可以不精通但是一定要了解,避免日常工作中贻笑大方
《信息化技能面试宝典相关博客》涉及信息化相关工作基础知识和面试技巧,提升自我能力与面试通过率,扩展知识面
《前端开发习惯与小技巧相关博客》持续更新中~罗列常用的开发工具使用技巧,如 Vscode快捷键操作、Git、CMD、游览器控制台等
《photoshop相关博客》持续更新中~基础的PS学习记录,含括PPI与DPI、物理像素dp、逻辑像素dip、矢量图和位图以及帧动画等的学习总结
日常开发&办公&生产【实用工具】分享相关博客》持续更新中~分享介绍各种开发中、工作中、个人生产以及学习上的工具,丰富阅历,给大家提供处理事情的更多角度,学习了解更多的便利工具,如Fiddler抓包、办公快捷键、虚拟机VMware等工具

吾辈才疏学浅,摹写之作,恐有瑕疵。望诸君海涵赐教。望轻喷,嘤嘤嘤

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。愿斯文对汝有所裨益,纵其简陋未及渊博,亦足以略尽绵薄之力。倘若尚存阙漏,敬请不吝斧正,俾便精进!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询