Fork Me On Github

小程序Mini-Timer开发(二)http封装

基本请求封装 Promise

  1. 普通请求
interface IRequestOption {
    headers?: any;
    mask?: boolean;
    loading?: boolean;
    guest?: boolean; // token失效不自动跳转
}

interface IRequest extends IRequestOption {
    url: string;
    params?: any;  // 拼接到url上
    data?: any;    // post 数据
}

export function request<T>(method: 'OPTIONS'| 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT', requestHandler: IRequest, option?: IRequestOption) {
    if (option) {
        // 多加一个 option 是方便进一步封装传入自定义配置
        requestHandler = Object.assign(requestHandler, option);
    }
    let { url, params, data, headers, mask, loading, guest } = requestHandler;
    if (loading === undefined || loading) {
        // 自动显示加载中
      wx.showLoading && wx.showLoading({title: 'Loading...', mask: mask ? mask : false})
    }
    if (!params) {
        params = {};
    }
    if (!headers) {
        headers = {};
    }
    // 这里可以加入自定义接口appid 和签名
    const token = wx.getStorageSync(TOKEN_KEY)
    if (token) {
        // 加入登录令牌
        headers.Authorization = 'Bearer ' + token;
    }
    return new Promise<T>((resolve, reject) => {
        wx.request({
            url: util.uriEncode(util.apiEndpoint + url, params),
            data: data,
            method: ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'].indexOf(method) > -1 ? method : 'GET',
            header: Object.assign({
                'Content-Type': 'application/json',
                'Accept': 'application/json',
            }, headers),
            success: function (res) {
                const { data, statusCode } = res;
                if (statusCode === 200) {
                    resolve(data as any);
                    return;
                }
                if (statusCode !== 401 || !guest) {
                    // 自动显示错误提示
                    wx.showToast({
                        title: (data as any).message,
                        icon: 'none',
                        duration: 2000
                    });
                }
                if (statusCode === 401) {
                    app && app.setToken();
                    if (!guest) {
                        // 自动跳转到登录页
                        wx.navigateTo({
                            url: '/pages/member/login'
                        });
                    }
                }
                // 处理数据
                reject(res)
            },
            fail: function () {
                reject('Network request failed')
            },
            complete: function () {
                wx.hideLoading && wx.hideLoading()
            }
        })
    });
}
  1. 上传文件
/**
 * 上传文件
 * @param file 要上传文件资源的路径 (本地路径)
 * @param requestHandler 
 * @param name 上传文件的对应的 key
 */
export function uploadFile<T>(file: string, requestHandler: IRequest, name: string = 'file'): Promise<T> {
    let { url, params, data, headers, mask, loading } = requestHandler;
    if (loading === undefined || loading) {
      wx.showLoading && wx.showLoading({title: 'Loading...', mask: mask ? mask : false})
    }
    if (!params) {
        params = {};
    }
    if (!headers) {
        headers = {};
    }
    // 这里可以加入自定义接口appid 和签名
    const token = wx.getStorageSync(TOKEN_KEY)
    if (token) {
        // 加入登录令牌
        headers.Authorization = 'Bearer ' + token;
    }
    return new Promise<T>((resolve, reject) => {
        wx.uploadFile({
            url: util.uriEncode(util.apiEndpoint + url, params),
            formData: data,
            filePath: file,
            name,
            header: Object.assign({
                'Accept': 'application/json',
            }, headers),
            success: function (res) {
                const { data, statusCode } = res;
                if (statusCode === 200) {
                    resolve(data as any);
                    return;
                }
                wx.showToast({
                    title: (data as any).message,
                    icon: 'none',
                    duration: 2000
                });
                if (statusCode === 401) {
                    app && app.setToken();
                    wx.navigateTo({
                        url: '/pages/member/login'
                    });
                }
                // 处理数据
                reject(res)
            },
            fail: function () {
                reject('Network request failed')
            },
            complete: function () {
                wx.hideLoading && wx.hideLoading()
            }
        })
    });
}

需要的几种请求方式

  1. GET
/**
 * 封装get方法
 * @param url
 * @param data
 * @param loading 是否显示加载中
 * @returns {Promise}
 */
export function fetch<T>(url: string, params = {}, option?: IRequestOption): Promise<T> {
    return request<T>('GET', {
        url,
        params,
    }, option);
}
  1. POST
/**
 * 封装post请求
 * @param url
 * @param data
 * @param loading 是否显示加载中
 * @returns {Promise}
 */
export function post<T>(url: string, data = {}, option?: IRequestOption): Promise<T> {
    return request<T>('POST', {
        url,
        data,
    });
}
  1. PUT

/**
 * 封装put请求
 * @param url
 * @param data
 * @param loading 是否显示加载中
 * @returns {Promise}
 */
export function put<T>(url: string, data = {}, option?: IRequestOption) {
    return request<T>('PUT', {
        url,
        data,
    }, option);
}
  1. DELETE
/**
 * 删除请求
 * @param url 
 * @param loading 是否显示加载中
 */
export function deleteRequest<T>(url: string, option?: IRequestOption): Promise<T> {
    return request<T>('DELETE', {
        url,
    }, option);
}

请求头添加

自动添加登录令牌

const token = wx.getStorageSync(TOKEN_KEY)
if (token) {
    // 加入登录令牌
    headers.Authorization = 'Bearer ' + token;
}

响应处理

  1. 对令牌过期的处理

清除token 并跳转登录页面,但是一些页面又不想自动跳转到登录页,所以应该能传入设置

if (statusCode === 401) {
    app && app.setToken();
    wx.navigateTo({
        url: '/pages/member/login'
    });
}
  1. 登录推出的处理

  2. 相应失败的信息弹窗

  3. 请求加载进度的显示

有些地方不需要加载进度条,比如下拉加载更多,静默加载更好,不影响阅读

点击查看全文
0 17 0