美文网首页
【axios】请求401之后的校验弹窗

【axios】请求401之后的校验弹窗

作者: Adder | 来源:发表于2021-07-06 15:41 被阅读0次

之前做过的项目在处理请求的401状态码的时候,没有特殊要求的话,大部分处理是给用户一个提示“登录已超时”,然后跳转到登录页面。

这种情况下,其实对于刚刚报错401的那个请求,是没有成功的。需要用户重新进入到刚刚的操作步骤,并且重复他的上一次操作步骤

鉴于我们的平台中,某些环节存在较长的操作流程,整个步骤也较为繁琐和关联很多细节;于是考虑,做一个登录失效的拦截弹窗,达到重连,并且不中断原来的操作的效果。


📌设计思路

  • 在axios的response.status = 401处拦截
  • 弹窗中需要提示用户登录超时,需要填写登录密码,重新登录
  • 登录校验成功之后,重新启动刚才401失败的那个http请求,因要求记住失败时的请求参数。

🧙具体实现

实现方式是封装成一个重连验证组件Identification

我们需要通过,组件内的登录的这个异步操作的结果【是 or 否】,决定“是否重连”,因此可以使用promise
在组件内部,登录成功才会执行resolve回调。从弹出弹框到输入密码,到点击登录,这个操作也是异步的,所以在组件内部,可以通过eventEmitter进行通信,触发执行这个resolve回调。

组件需要暴露出两个api:

  1. showModal
  • 创建模态框,里面包括表单项、确认按钮,用于用户填写登录密码
  • eventEmitter.on注册登录后的成功回调resolveCallback, const ee = new EventEmitter();
  showModal: () => {
    return new Promise((resolve) => {
      // 注册回调方法
      ee.on('resolveCallback', (code) => {
        resolve(code);
      });

      const loginModalDom = document.getElementById('__login_modal');
      // 只弹出1个登录框
      if (!loginModalDom) {
        const div = document.createElement('div');
        div.id = '__login_modal';
        document.body.appendChild(div);
        ReactDOM.render(
          <LoginModal visible={true} onCancel={identification.removeModal} />,
          div,
        );
      }
    });
  }
  1. removeModal
    移除模态框
const identification = {
  ...showModal,
  removeModal: () => {
    const loginModalDom = document.getElementById('__login_modal');
    if (loginModalDom) {
      loginModalDom.remove();
    }
    ee.emit('resolveCallback', 0);//回调
  },
};
export default identification

🎇登录模态框

//FormModal
<Modal
 title="请重新登录"
 visible={visible}
 //...
>
   <div style={{ padding: '24px' }}>
      <Form
        //...
        onFinish={onFinish}
       >
         <Form.Item
          name="password"
          rules={[{ required: true, message: '请输入密码' }]}
         >
           <Input.Password />
         </Form.Item>
         <Form.Item>
           <Button htmlType="submit" type="primary" block>登录</Button>
         </Form.Item>
      </Form>
   </div>
</Modal>
//LoginModal
    const [form] = Form.useForm();
    const { visible = false, onCancel } = props;
    const [errorText, setErrorText] = useState('');

    async function onFinish(values: any) {
      const res = await login({
        data: values,
        errorHandler: (e) => {
          setErrorText(e.message);
        },
      });
      const { code, data } = res;
      if (code === 0) {
        //...
        ee.emit('resolveCallback', 1); //回调
      }
    }
    return (<FormModal/>);

🧪使用

//在axios的状态码401断言下,处理操作
case(status === 401) :
//...
const callbackCode = await identification.showModal();
if (callbackCode === 1) {
    identification.removeModal();
    // 登录成功后,重发之前失败的请求
    //这里的option是直接在axios封装体中,直接可以拿到的
    const res = await request(option);
    return Promise.resolve(res);
} else {
    //...处理相关的异常逻辑
    return Promise.resolve({
      code: error?.response?.status || defaultErrorCode,
      data: null,
      error: errorText,
    });
}

📎参考

查看源代码逻辑,根据业务在代码中包括一些状态管理的操作,可以忽视💦

相关文章

网友评论

      本文标题:【axios】请求401之后的校验弹窗

      本文链接:https://www.haomeiwen.com/subject/pwhgultx.html