目录
- 1. 创建目录结构
- 2. 全局通用的config的变量配置
- 3. 配置http网络请求
- 4. 使用
1. 创建目录结构
- 在 src 目录下新建 service 目录,目录下创建 api 和 http 子目录
- 在 src 目录下新建 config 配置文件
2. 全局通用的config的变量配置
在 config 文件中添加一下代码:
const debug = process.env.NODE_ENV !== "production";
export default {
debug, //是否为开发环境
baseUrl: "http://192.168.1.1:3000", // 基本接口
//请求状态码
SUCCESS: 200,
CREATED: 201,
ACCEPTED: 202,
CLIENT_ERROR: 400,
AUTHENTICATE: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
SERVER_ERROR: 500,
BAD_GATEWAY: 502,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504,
defineConstants: {
LOCATION_APIKEY: JSON.stringify("IWYBZ-OGUKR-LK7WQ-W2AC5-XEHIJ-WDB24")
}
};
3. 配置http网络请求
- 在 http 目录下新建 url.js 文件对 http 请求的 url 进行解析:
import config from '../../config'
const baseUrl = config.baseUrl; //基本接口地址
/**
* GET 请求时,拼接请求URL
* @param url 请求URL
* @param params 请求参数
* @returns {*}
*/
const handleUrl = url => params => {
if (params) {
let paramsArray = [];
Object.keys(params).forEach(key => paramsArray.push(key + '=' + encodeURIComponent(params[key])));
if (url.search(/\?/) === -1) {
typeof (params) === 'object' ? url += '?' + paramsArray.join('&') : url
} else {
url += '&' + paramsArray.join('&')
}
}
return baseUrl + url;
};
export { handleUrl }
- 在 http 目录下新建 interceptors.js 文件用于拦截网络请求:
- 在 Taro 中的 Taro.addInterceptor 方法用于拦截网络请求,并可以对请求和响应进行处理。它拦截的是网络请求的状态,而不是接口返回的状态。
- 具体来说,Taro.addInterceptor 方法允许你添加一个拦截器函数,在发送请求和接收响应的过程中进行拦截和处理。你可以在拦截器函数中对请求进行预处理,例如添加请求头、修改请求参数等,并对响应进行处理,例如检查响应状态码、解析响应数据等。
- 这个拦截器函数在网络请求过程中被调用,并且可以访问请求的相关信息,如请求参数、请求方法、请求头等,以及响应的相关信息,如状态码、响应头、响应数据等。
import config from "../../config";
/**
* 在调用 Taro.request 发起请求之前,调用 Taro.addInterceptor 方法为请求添加拦截器,拦截器的调用顺序遵循洋葱模型。 拦截器是一个函数,接受 chain 对象作为参数。
* chain 对象中含有 requestParmas 属性,代表请求参数。拦截器内最后需要调用 chain.proceed(requestParams) 以调用下一个拦截器或发起请求。
* Taro 提供了两个内置拦截器 logInterceptor 与 timeoutInterceptor,分别用于打印请求的相关信息和在请求超时时抛出错误。
*/
/**
* 自定义请求结果拦截器,用户处理公共的返回值配置内容等
* @param {*} chain
*/
const customInterceptors = (chain) => {
const requestParams = chain.requestParams; //请求参数
// console.log(requestParams, "requestParams");
//返回一个Promis
return chain.proceed(requestParams).then(res => {
// console.log(res.statusCode, "res.statusCode");
// 只要请求成功,不管返回什么状态码,都走这个回调
switch (res.statusCode) {
//404
case config.NOT_FOUND:
return Promise.reject({ desc: '请求资源不存在' });
//502
case config.BAD_GATEWAY:
return Promise.reject({ desc: '服务端出现了问题' });
//403
case config.FORBIDDEN:
return Promise.reject({ desc: '没有权限访问' });
//401
case config.AUTHENTICATE:
return Promise.reject({ desc: '需要鉴权:' + config.AUTHENTICATE });
//500
case config.SERVER_ERROR:
return Promise.reject({ desc: '服务器错误' });
//200
case config.SUCCESS:
//请求成功的返回值
return res.data;
default:
return Promise.reject({ desc: "" })
}
}).catch(error => {
return Promise.reject(error)
})
}
//可扩展多个拦截器
const interceptors = [customInterceptors];
//导出拦截器的数组
export default interceptors;
- 在 src 目录下新建 httpUtils.js 文件用于配置 http 的请求封装工具:
//引入基础库
import Taro from "@tarojs/taro";
import config from "../../config";
import interceptors from "./interceptors";
import { handleUrl } from "./url";
//添加 Taro的拦截请求
interceptors.forEach(interceptorItem => Taro.addInterceptor(interceptorItem));
class HttpUtils {
/**
* 请求公共方法
* @param {*} method Request的method类型 post 或者 get
* @param {*} url 请求的接口
* @param {*} params 请求参数
* @param {*} header 自定义请求头
* @returns 返回promise 对象
*/
RequestOptions (method = "GET", url = "", params = {}, header = null) {
const baseUrl = config.baseUrl;
let { contentType = "application/json" } = header || {};
let loginToken = Taro.getStorageSync("logintoken") || "";
let requestUrl = url;
if (requestUrl.indexOf("http") < 0) {
requestUrl = method == "GET" ? handleUrl(requestUrl)(params) : baseUrl + requestUrl;
}
let option = {
url: requestUrl, //地址
data: method == "GET" ? {} : { ...params }, //传参
method: method, //请求方式
timeout: 30000, // 超时时间
header: { //请求头
'content-type': contentType,
'token': loginToken, // 临时token
...header,
}
};
if (url.indexOf("/imapi/") >= 0) {
option = {
url: config.imlocalserverUrl + url,
method: method, //请求方式
data: method == "GET" ? {} : { ...params }, //传参
timeout: 30000, // 超时时间
header: { //请求头
'content-type': contentType,
'token': loginToken, // 临时token
...header,
}
}
}
return Taro.request(option).then((res) => {
if (!res.data) return;
const { status, msg } = res.data;
// console.log("请求的内容", res);
// 对接口返回状态进行处理
if (status == 201) {
// 错误信息
Taro.showToast({
title: msg,
icon: 'none',
duration: 1500
})
} else if (status == 202) {
// ... 无token时退出登录的处理
return null;
}
return res.data;
}).catch((rejectvalue) => {
console.log("网络请求异常", rejectvalue, option);
return null;
});
}
/**
* Taro的get基础请求
* @param {*} url
* @param {*} params
* @returns
*/
getRequest = (url, params = {}) => {
return this.RequestOptions("GET", url, params);
}
/**
* Taro的POST请求
* @param {*} url
* @param {*} params
* @returns
*/
postRequest = (url, params, header = {}) => {
return this.RequestOptions("POST", url, params, header);
}
}
export default new HttpUtils();
- 在 src 目录下新建 index.js 文件进行 http 请求:
import HttpUtils from "./httpUtils";
/**
* 从缓存中读取数据
* @param isCache 是否缓存 预留缓存配置
* @param requestType 请求类型
* @returns {function(*=, *=, *=): (*|*)}
*/
const RequestData = (isCache = false, requestType) => (url, params, callback) => {
// console.log(url, params);
//默认的执行函数
const requestFunc = (result) => {
if (result) {
if (callback && typeof callback === 'function') {
return callback(result);
} else {
return result;
}
}
//返回出来的promise
let promise = requestType === 'GET' ? HttpUtils.getRequest(url, params) : requestType === 'POST' ? HttpUtils.postRequest(url, params) : HttpUtils.postRequest(url, params, { contentType: "application/json" }); //去网络拿数据
if (callback && typeof callback === 'function') {
promise.then(response => {
return callback(response)
})
}
return promise;
};
if (isCache) {
return null;
}
// 预留缓存配置
return requestFunc();
};
/**
* GET 请求
*/
const Get = RequestData(false, 'GET');
/**
* POST 请求
*/
const Post = RequestData(false, 'POST');
/**
* 上传文件,上传图片
*/
const UploadFile = RequestData(false, "File");
export { Get, Post, UploadFile };
4. 使用
在 api 目录下新建 index.js 文件:
import { Get, Post, UploadFile } from '../http';
export const postText= data => Post('/api/post_text', data);
将接口导入文件使用。