前后端分离使用localStorage替代cookies并封装到umi-request组成跨终端请求插件wldos-request

做过的都知道,cookies不是万能的,为了兼容移动端可以采用localStorage,然后做一些封装实现类cookies功能。前端token等凭据的保存依赖于HTTP请求和响应,umi3.0的umi-插件是个好用的插件,两者结合就成了本文所述的跨终端请求插件。

本插件包含两部分:localStorage封装和request封装。

localstorage封装代码如下:

const expirefix = "__expires__";
/**
 * @desc 在localStorage基础上封装支持过期时间的storage,代替cookie。
 * @author .com
 * @version 1.0
 */
class wldostorage {

    constructor() {
        this.source = localStorage;
        this.init();
    }

    init(){
        /**
        * @desc 初始化localstorage
        * @param {String} key 键
        * @param {String} value 值,若存储数组、对象,需要通过JSON.stringify转换为json字符串
        * @param {String} expired 过期时间,以分钟为单位
        */
        const reg = new RegExp(expirefix);
        const data = this.source;
        const list = Object.keys(data);
        if(list.length > 0){
            list.map((item)=>{
                const { key } = item;
                if( !reg.test(key)){
                    const now = Date.now();
                    const expires = data[`${key}${expirefix}`]||Date.now+1;
                    if (now >= expires ) {
                        this.remove(key);
                    };
                };
                return key;
            });
        };
    }

    remove(key) {
        const data = this.source;
        const value = data[key];
        delete data[key];
        delete data[`${key}${expirefix}`];
        return value;
    }

    get(key) {
        /**
        * @desc 从localstorage获取项
        * @param {String} key 键
        * @param {String} expired 存储时为非必须字段,所以有可能取不到,默认为 Date.now+1
        */
        const { source } = this;
        const expired = source[`${key}${expirefix}`]||Date.now+1;
        const now = Date.now();
        console.log('wldostorage get>>>', source, expired, now);

        if ( now >= expired ) {
            this.remove(key);
            return undefined;
        }

        return source[key] ? JSON.parse(source[key]) : source[key];
    }


    set(key, value, expired) {
        /**
        * @desc 设置localStorage项
        * @param {String} key 键
        * @param {String} value 值
        * @param {Number} expired 过期时间,以分钟为单位,非必填
        */
        const { source } = this;
        source[key] = JSON.stringify(value);
        if (expired){
            source[`${key}${expirefix}`] = Date.now() + 1000*60*expired
        };
        return value;
    }
}
// eslint-disable-next-line new-cap
const  = new wldostorage();

[/erphpdown]
export default ;

与umi-request结合封装代码如下:

/**
 * umi-request 网络请求工具
 * 更详细的 api 文档: umi-rqeust
 */
import { extend } from 'umi-request';
import { notification } from 'antd';
import {refreshTokenService} from "@/services/login";
import {setAuthority} from "@/utils/authority";
import  from "@/utils/wldostorage";

const codeMessage = {
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队(异步任务)。',
  204: '删除数据成功。',
  400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限(令牌、用户名、密码错误)。',
  403: '用户得到授权,但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
  406: '请求的格式不可得。',
  410: '请求的资源被永久删除,且不会再得到的。',
  422: '当创建一个对象时,发生一个验证错误。',
  500: '服务器发生错误,请检查服务器。',
  502: '网关错误。',
  503: '服务不可用,服务器暂时过载或维护。',
  504: '网关超时。',
};

/**
 * 处理程序
 */
const errorHandler = (error) => {
    const { response } = error;

    if (response && response.status) {
        const errorText = codeMessage[response.status] || response.statusText;
        const { status, url } = response;
        notification.error({
            message: `请求错误 ${status}: ${url}`,
            description: errorText,
        });
    } else if (!response) {
        notification.error({
            description: '您的网络发生,无法连接服务器',
            message: '网络',
        });
    }

    return response;
};

/**
 * 配置request请求时的默认参数
 */
const req = extend({
    errorHandler, // 默认错误处理
    credentials: 'include', // 默认请求是否带上cookie
});

const request = (url, params) => {
    const { method = 'GET' } = params || {};
    const options = {
        method,
        headers: { // umi-request默认Content-Type为application/json,此处省略。
            'X-CU-AccessToken-WLDOS': .get('accessToken'),
        },
    };
   if (method === 'GET') {
        Object.assign(options,
            // method为get,umi-request默认为get
            params, // get方法数据域schema为params,表示请求参数,完整写法是:params: {key: value,...}
        );
    } else {
        Object.assign(options, {
            // method可以为:POST、PATCH、PUT、DELETE
            data: params.data, // post方法数据域schema为data,表示要提交的数据,完整写法是:data: {key: value,...}
        });
    }

    console.log('request>> url, params, options>>>>', url, params, options);

    return req(url, options)
        /* .then((res) => {
        return checkStatus(res, url, options);
    }) .catch(err => ({
        err
    })) */;
};
// 文件上传
const postFile = (url, params) => {
    const formData = new FormData();
    formData.append('file', params);
    return request(url, { method:'post', data: formData });
};
export { postFile };
export default request;

// 使用方法示例:
// POST请求:
export async function queryCurrentBook(params) {
  return request('/api/currentBook', {
      method: 'POST',
      data: params,
  });
}
// GET请求:
export async function queryCurrentChapter(params) {
    return request('/api/currentChapter', {
        params,
    });
}

// mock接收参数示例:
'POST /api/currentBook': async (req, res) => {
      const { userid, bookId } = req.body; 
      console.log('当前年谱id:', userid, req.body);
}

'GET /api/currentChapter': async (req, res) => {
     const {userid, chapterId, bookId } = req.query;
     console.log('请求章节userid, bookId, chapterId, req.body:', userid, bookId, chapterId, req.query);
}

声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 智乐兔
转载请注明:转自《前后端分离使用localStorage替代cookies并封装到umi-request组成跨终端请求插件wldos-request
本文地址:https://www.zhiletu.com/archives-10929.html
关注公众号:智乐兔

赞赏

wechat pay微信赞赏alipay pay支付宝赞赏

上一篇
下一篇

相关文章

在线留言

你必须 登录后 才能留言!

  1. 科乐

    解决了一个小问题,感谢分享。

在线客服
在线客服 X

售前: 点击这里给我发消息
售后: 点击这里给我发消息

智乐兔官微