# 请求层基类 Fetcher.js - [请求层基类 Fetcher.js](#请求层基类-fetcherjs) - [功能说明](#功能说明) - [引用方法](#引用方法) - [构造函数](#构造函数) - [主要方法](#主要方法) - [`spellURL(devSuffix, serSuffix)`](#spellurldevsuffix-sersuffix) - [`get(url, data, options)`](#geturl-data-options) - [`post(url, data, options)`](#posturl-data-options) - [`query(type, url, data, options)`](#querytype-url-data-options) - [`stringToCamel(str)`](#stringtocamelstr) - [`stringToUnderline(str)`](#stringtounderlinestr) - [`transKeyName(type, json)`](#transkeynametype-json) - [请求的 options 配置](#请求的-options-配置) - [`hostType` 主机类型](#hosttype-主机类型) - [`silence` 静音请求](#silence-静音请求) - [响应处理](#响应处理) - [处理流程](#处理流程) - [前端统一响应数据格式](#前端统一响应数据格式) - [前端统一响应状态码](#前端统一响应状态码) - [请求调用](#请求调用) ## 功能说明 类 Fetcher 是一个用于处理 HTTP 请求的基类,包含了URL拼接、响应数据适配、报错提示等多种方法来简化和统一请求的处理 请求层的每个请求集,都必须继承此类 ## 引用方法 ```js import { Fetcher } from '@components/bases/Fetcher'; ``` ## 构造函数 构造函数接受一个配置对象 options 作为参数,包含如下属性: * **urlPrefix** 数组,包含两项,第一项为本地 Mock 的 URL 前缀,第二项为服务器接口的前缀 ```js class FCommon extends Fetcher { constructor() { // 构造函数使用示例 super({ urlPrefix: ['/api/order/', '/mini/order/'], }); } } ``` ## 主要方法 ### `spellURL(devSuffix, serSuffix)` **功能** 根据开发环境和生产环境拼接 URL 地址 **参数** - `devSuffix` (String):开发环境下的 URL 后缀 - `serSuffix` (String, 可选):生产环境下的 URL 后缀。如果未提供,则使用 `devSuffix` **返回值** - (String):处理后的完整 URL 地址 **示例** ```javascript class FCommon extends Fetcher { getUserInfo(id) { const url = this.spellURL('getUserInfo', 'user/user_info'); } } ``` **注意事项** - 如果启用了 Mock 模式(比如本地开发时),URL 会指向本地的 JSON 文件 - 自动处理路径中的 `../` 和多余的 `/`,确保路径正确 --- ### `get(url, data, options)` **功能** 发起 GET 请求 **参数** - `url` (String):请求的 URL 地址 - `data` (Object):请求参数 - `options` (Object,可选):请求配置 **返回值** - (Promise):返回请求结果的 Promise --- ### `post(url, data, options)` **功能** 发起 POST 请求,query 方法的简写 **参数** - `url` (String):请求的 URL 地址 - `data` (Object):请求参数 - `options` (Object,可选):请求配置 **返回值** - (Promise):返回请求结果的 Promise **示例** ```js class FCommon extends Fetcher { getUserInfo() { const url = this.spellURL('getUserInfo', 'user/user_info'); const send = {}; return this.post(url, send); } } ``` --- ### `query(type, url, data, options)` **功能** 发起基础 AJAX 请求 **参数** - `type` (String):请求类型(如 `'get'`、`'post'`) - `url` (String):请求的 URL 地址 - `data` (Object,可选):请求参数 - `options` (Object,可选):请求配置 **返回值** - (Promise):返回请求结果的 Promise **注意事项** - 小程序环境下会自动处理 Cookie,无需手动设置 --- ### `stringToCamel(str)` **功能** 将下划线命名的字符串转换为小驼峰命名 **参数** - `str` (String):需要转换的字符串 **返回值** - (String):转换后的小驼峰字符串 --- ### `stringToUnderline(str)` **功能** 将小驼峰命名的字符串转换为下划线命名,如果没有大写字母,则返回原字符串 **参数** - `str` (String):需要转换的字符串 **返回值** - (String):转换后的下划线字符串 --- ### `transKeyName(type, json)` **功能** 将 JSON 对象的键名在驼峰与下划线命名模式之间转换 **参数** - `type` (String):转换的目标类型,有两个值: - `'camel'`:下划线转小驼峰 - `'underline'`:小驼峰转下划线 - `json` (Object):需要转换的 JSON 对象 **返回值** - (Object):转换后的 JSON 对象 **示例** ```js class FCommon extends Fetcher { saveUserInfo() { const json = { 'user_name': 'John' }; const result = this.transKeyName('camel', json); // 返回 { userName: 'John' } } } ``` **注意事项** - 支持嵌套对象的递归转换 ## 请求的 options 配置 ### `hostType` 主机类型 在混合 App 中,指定本次请求的主机类型(即域名),有两个值: - `base`:基础主机(预登陆用) - `main`:默认主机,默认值,正常业务主机 - 优先由 java 层在 webview 的 URL 上指定 - 未指定时,按文件 project.config.json 的 host.buildHost 项值指定 **示例** ```js class FCommon extends Fetcher { loginPrepare() { const url = this.spellURL('loginPrepare', 'User/preLogin'); const send = {}; return this.post(url, send, { hostType: 'base' }); } } ``` ### `silence` 静音请求 设为 true 时,如果请求失败,不显示提示 **示例** ```js class FCommon extends Fetcher { getUserInfo() { const url = this.spellURL('getUserInfo', 'User/info'); const send = {}; return this.post(url, send, { silence: true }); } } ``` ## 响应处理 ### 处理流程 1. query 方法调用 Taro.request 发送请求 2. 收到响应后,先检测响应数据格式,发现其他类型的响应格式时,会自动转换为:**前端统一响应数据格式** 3. 根据响应格式 - 如果成功,将响应内容,回传给数据控制层 - 如果失败,直接失败提示,回传空内容给数据控制层 4. 将响应内容传给数据控制层之前,会进行如下处理 - 将数据中的键名,转换为的驼峰 - 将数据中的内容,如果是常规数字的字符串,转为数值 ### 前端统一响应数据格式 格式如下: ```js { state: { // 状态 code, // 状态码 msg // 状态消息 }, data: { // 实际数据,必须是 Object } } ``` 例如: ```json { "state": { "code": 2000, "msg": "OK" }, "data": { "id": 1, "name": "Tevin" } } ``` 注意,为了保证接口数据的扩展性,data 只能接 Object 类型,禁止接其他类型 ### 前端统一响应状态码 - `2000`:通用请求成功 - `2001`:请求成功,但是没有数据,弹窗提示 msg(仅特殊情况使用) - `5000`:通用请求失败,弹窗提示 msg - `9001`:登录已过期,返回登录页 - `9002`:已登录但没有操作权限,弹窗提示 msg ## 请求调用 请求层的每一个请求集,都会实例化自身作为全局单例,使用时,只需引用已经实例化好的全局单例,直接发请求即可 ```js import { Fetcher } from '@components/bases/Fetcher'; class FCommon extends Fetcher {} // 全局单例 export const $fetchCommon = new FCommon(); ``` ```js import { $fetchCommon } from '@fetchers/FCommon'; export class PPageName extends Pilot { // 在数据控制层中,发请求示例 onLoadUserInfo() { Taro.showLoading(); $fetchCommon.getUserInfo(this.userId) .then(res => { Taro.hideLoading(); if (!res) { return; } this.userInfo = res || {}; }); } } ```