问题起因
聊到网路请求调试,除了 debugger 和 mock 接口,其实可以直接在浏览器中拦截接口响应。
这是在某些场景下更优雅的操作。
比如,我们遇到一个需求,项目使用了 vform3 这个库,然后希望一个接口同时返回我们期望的所有 form 组件,这时候大部分前端肯定是去代码中注释掉真实接口(或者用现成的插件),然后手写一个 mock 接口填上我们需要的返回值。但是这种方法太笨重,项目代码繁杂,需要注释-> 调试-> 修改代码-> 解开注释这一系列过程。
因此,我这里说一种更加优雅的调试技巧。
优雅方案
浏览器中支持对接口响应内容的重写,不知道同学们知不知道,我们可以直接从这里入手,步骤如下:
- F12 打开 DevTools → Network 面板 → 勾选 Disable cache(避免缓存干扰)
- 打开"xx 详情"抽屉(我们需要触发接口的页面),触发一次请求
- 在 Network 列表里找到
getFormData请求(需要改写的那个接口) - 右键 → Override content(首次会提示启用 Overrides 文件夹,选个我们项目根目录确定即可)
- 把我们需要的 mock JSON(返回值/响应值) 粘贴替换,保存
- 刷新页面重新打开抽屉 → 请求会走 mock 数据
比如 mock JSON:
JSON
{
"success": true,
"data": {
"form": {
"formType": 2,
"formId": "mock_vform_test",
"meta": {
"widgetList": [
{
"type": "input", "icon": "text-field", "formItemFlag": true, "id": "field_input_1",
"options": { "name": "inputText", "label": "单行输入", "labelAlign": "", "type": "text",
"defaultValue": "单行输入示例值", "placeholder": "请输入", "columnWidth": "200px",
"labelWidth": null, "labelHidden": false, "readonly": false, "disabled": true,
"hidden": false, "clearable": true, "showPassword": false, "required": false,
"requiredHint": "", "validation": "", "validationHint": "", "customClass": "",
"minLength": null, "maxLength": null, "showWordLimit": false,
"prefixIcon": "", "suffixIcon": "", "appendButton": false,
"appendButtonDisabled": false, "buttonIcon": "",
"onCreated": "", "onMounted": "", "onInput": "", "onChange": "", "onFocus": "", "onBlur": "", "onValidate": "" }
},
{
"type": "textarea", "icon": "textarea-field", "formItemFlag": true, "id": "field_textarea_1",
"options": { "name": "textareaText", "label": "多行输入", "labelAlign": "", "rows": 3,
"defaultValue": "多行输入示例值", "placeholder": "请输入", "columnWidth": "200px",
"labelWidth": null, "labelHidden": false, "readonly": false, "disabled": true,
"hidden": false, "required": false, "requiredHint": "", "validation": "", "validationHint": "",
"customClass": "", "minLength": null, "maxLength": null, "showWordLimit": false,
"onCreated": "", "onMounted": "", "onInput": "", "onChange": "", "onFocus": "", "onBlur": "", "onValidate": "" }
},
{
"type": "radio", "icon": "radio-field", "formItemFlag": true, "id": "field_radio_1",
"options": { "name": "radioGroup", "label": "单选", "labelAlign": "", "defaultValue": 1,
"columnWidth": "200px", "labelWidth": null, "labelHidden": false, "disabled": true,
"hidden": false, "required": false, "requiredHint": "", "validation": "", "validationHint": "",
"customClass": "", "optionItems": [
{ "label": "合理", "value": 1 }, { "label": "有创新", "value": 2 },
{ "label": "不完善", "value": 3 }, { "label": "有误", "value": 4 }
], "showButtonStyle": false, "displayType": "row",
"onCreated": "", "onMounted": "", "onChange": "", "onValidate": "" }
},
{
"type": "checkbox", "icon": "checkbox-field", "formItemFlag": true, "id": "field_checkbox_1",
"options": { "name": "checkboxGroup", "label": "多选", "labelAlign": "", "defaultValue": [1, 2],
"columnWidth": "200px", "labelWidth": null, "labelHidden": false, "disabled": true,
"hidden": false, "required": false, "requiredHint": "", "validation": "", "validationHint": "",
"customClass": "", "optionItems": [
{ "label": "有创意", "value": 1 }, { "label": "无新意但可作为资料", "value": 2 },
{ "label": "有自己的经验", "value": 3 }, { "label": "无参考价值", "value": 4 }
], "showButtonStyle": false, "displayType": "row",
"onCreated": "", "onMounted": "", "onChange": "", "onValidate": "" }
},
{
"type": "button", "icon": "button", "formItemFlag": false, "id": "field_button_1",
"options": { "name": "submitBtn", "label": "按钮", "columnWidth": "200px",
"size": "", "displayStyle": "block", "disabled": true, "hidden": false,
"type": "primary", "plain": false, "round": false, "circle": false, "icon": null,
"customClass": "", "onCreated": "", "onMounted": "", "onClick": "" }
},
{
"type": "rich-editor", "icon": "rich-editor-field", "formItemFlag": true, "id": "field_rich_1",
"options": { "name": "richText", "label": "富文本", "labelAlign": "", "placeholder": "",
"labelWidth": null, "labelHidden": false, "columnWidth": "200px", "disabled": true,
"hidden": false, "required": false, "requiredHint": "", "customRule": "", "customRuleHint": "",
"customClass": "", "minLength": null, "maxLength": null, "showWordLimit": false,
"onCreated": "", "onMounted": "", "onValidate": "" }
}
],
"formConfig": {
"modelName": "formData", "labelPosition": "left", "labelWidth": 120,
"labelAlign": "right", "size": "default", "disabled": true,
"hideRequiredMark": false, "customStyle": ""
}
}
},
"data": {
"inputText": "单行输入示例值",
"textareaText": "多行输入示例值",
"radioGroup": 1,
"checkboxGroup": [1, 2],
"richText": "<p>富文本<b>加粗</b>示例内容</p>"
}
}
}
常规方案
getFormData 函数里临时加一段(用完记得删):
TypeScript
const getFormData = async () => {
// ===== 临时 mock 开始(测完删除)=====
const mock = { /* 上面 JSON 的 data 部分 */ };
// 直接把 mock 赋值给 form / formData,跳过请求
// ===== 临时 mock 结束 =====
// ...
};
相比之下,另一个方案是不是更优雅了呢?