全栈开发笔记之功能组件(三)axios拦截器配置

5 篇文章 0 订阅
1 篇文章 0 订阅

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请求流程

1. 客户端点击按钮发起请求

在这里插入图片描述

2.请求拦截器拦截并处理请求

3.服务器收到请求,处理后返回相应的状态和数据

4.响应拦截器拦截并处理请求

5.如果res.data.code === 200,提示成功信息,返回数据,接着执行.then(res =>{…});否则提示错误信息,不往下执行。

vue目录结构

在这里插入图片描述

package.json

...
"dependencies": {
    "core-js": "^2.6.5",
    "axios": "0.21.0",
    "element-ui": "^2.15.1",
    "jsencrypt": "^3.1.0",
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.0.4",
    "@vue/cli-plugin-eslint": "^3.0.4",
    "@vue/cli-service": "^3.0.4",
    "babel-eslint": "^10.0.1",
    "eslint": "^5.16.0",
    "sass": "1.32.0",
    "sass-loader": "10.1.0",
    "eslint-plugin-vue": "^5.0.0",
    "vue-template-compiler": "^2.6.10"
  },
  ...

main.js

import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

App.vue

<template>
  <div id="app">
    <login />
  </div>
</template>

<script>
import Login from '@/views/login'
export default {
  name: 'app',
  components: {
    Login
  }
}
</script>

<style>
  * {
    margin: 0;
    padding: 0;
  }
  /*撑开内容充满整个页面*/
  #app {
    position: absolute;
    width: 100%;
    top: 0;
    bottom: 0;
  }
</style>

request.js(配置axios)

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import Cookies from 'js-cookie'

const TokenKey = 'Admin-Token'

// 设置请求头
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const http = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: 'http://localhost:8080/',
  // 超时
  timeout: 10 * 1000
})
// 请求拦截器
http.interceptors.request.use(config => {
  let token = Cookies.get(TokenKey);
  console.log(token)
  if (token) {
    // 让每个请求携带自定义token 请根据实际情况自行修改
    config.headers['Authorization'] = 'Bearer ' + token;
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?';
    for (const propName of Object.keys(config.params)) {
      const value = config.params[propName];
      var part = encodeURIComponent(propName) + "=";
      if (value !== null && typeof(value) !== "undefined") {
        if (typeof value === 'object') {
          for (const key of Object.keys(value)) {
            let params = propName + '[' + key + ']';
            var subPart = encodeURIComponent(params) + "=";
            url += subPart + encodeURIComponent(value[key]) + "&";
          }
        } else {
          url += part + encodeURIComponent(value) + "&";
        }
      }
    }
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  return config
}, error => {
  console.log(error)
  Promise.reject(error)
})

// 响应拦截器
http.interceptors.response.use(res => {
    const code = res.data.code;
    const msg = res.data.msg;
    if (code === 200) {
      Cookies.set(TokenKey, res.data.tokenKey);
      Message.success(msg);
      return res.data;
    } else if (code === 401) {
      MessageBox.confirm('登录状态已过期,请您重新登录', '系统提示', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        Cookies.remove(TokenKey);
        location.href = '/login';
      })
    } else {
      Message.error(msg);
      return Promise.reject(msg)
    }
  },
  error => {
    console.log("" + error)
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
    }
    else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    }
    else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    Message.error(message)
    return Promise.reject(error)
  }
)

export default http

login.js

import http from '@/utils/request'

// 保存登录信息
export function insertLoginInfo(params) { return http.post('/login', params) }
//获取登录信息
export function getLoginInfo(params) { return http.get('/login', {params}) }

login.vue

<template>
  <div class="login">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
      <h3 class="title">账号密码登录</h3>
      <el-form-item prop="username">
        <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
          v-model="loginForm.password"
          type="password"
          auto-complete="off"
          placeholder="密码"
          @keyup.enter.native="handleLogin"
        >
        </el-input>
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
      <el-form-item>
        <el-row>
          <el-col :span="8">
            <el-button
              :loading="loading"
              size="medium"
              type="primary"
              @click.native.prevent="handleLogin"
            >
              <span v-if="!loading">get</span>
              <span v-else>loading...</span>
            </el-button>
          </el-col>
          <el-col :span="8">
            <el-button
              :loading="loading"
              size="medium"
              type="primary"
              @click.native.prevent="handleLogin2"
            >
              <span v-if="!loading">post</span>
              <span v-else>loading...</span>
            </el-button>
          </el-col>
        </el-row>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <span>Copyright © 2018-2021 All Rights Reserved.</span>
    </div>
  </div>
</template>

<script>
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
import { insertLoginInfo, getLoginInfo } from "@/api/login";

export default {
  name: "Login",
  data() {
    return {
      cookiePassword: "",
      loginForm: {
        username: "admin",
        password: "admin",
        rememberMe: false,
      },
      loginRules: {
        username: [{ required: true, trigger: "blur", message: "用户名不能为空" }],
        password: [{ required: true, trigger: "blur", message: "密码不能为空" }]
      },
      loading: false,
    };
  },
  created() {
    this.getCookie();
  },
  methods: {
    getCookie() {
      const username = Cookies.get("username");
      const password = Cookies.get("password");
      const rememberMe = Cookies.get('rememberMe')
      this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        password: password === undefined ? this.loginForm.password : decrypt(password),
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
      };
    },
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true;
          if (this.loginForm.rememberMe) {
            Cookies.set("username", this.loginForm.username, { expires: 30 });
            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
          } else {
            Cookies.remove("username");
            Cookies.remove("password");
            Cookies.remove('rememberMe');
          }
          getLoginInfo(this.loginForm).then(()=>{
            this.loading = false;
          })
        }
      });
    },
    handleLogin2() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true;
          if (this.loginForm.rememberMe) {
            Cookies.set("username", this.loginForm.username, { expires: 30 });
            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
          } else {
            Cookies.remove("username");
            Cookies.remove("password");
            Cookies.remove('rememberMe');
          }
          insertLoginInfo(this.loginForm).then(()=>{
            this.loading = false;
          })
        }
      });
    }
  }
};
</script>

<style rel="stylesheet/scss" lang="scss">
.login {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  background-image: url("../assets/images/login-background.png");
  background-size: cover;
}
.title {
  margin: 0px auto 30px auto;
  text-align: center;
  color: #707070;
}

.login-form {
  border-radius: 6px;
  background: #ffffff;
  width: 300px;
  padding: 25px 25px 5px 25px;
  .el-input {
    height: 38px;
    input {
      height: 38px;
    }
  }
  .input-icon {
    height: 39px;
    width: 14px;
    margin-left: 2px;
  }
}
.login-tip {
  font-size: 13px;
  text-align: center;
  color: #bfbfbf;
}
.login-code {
  width: 33%;
  height: 38px;
  float: right;
  img {
    cursor: pointer;
    vertical-align: middle;
  }
}
.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}
</style>

jsencrypt.js

import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'

// 密钥对生成 http://web.chacuo.net/netrsakeypair

const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='

const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
  'UP8iWi1Qw0Y='

// 加密
export function encrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(txt) // 对数据进行加密
}

// 解密
export function decrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey) // 设置私钥
  return encryptor.decrypt(txt) // 对数据进行解密
}


springboot目录结构

在这里插入图片描述

pom.xml

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.13.RELEASE</version>
        </dependency>

主启动类

package com.yxtycs;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author yuxt
 * @date 2021/4/17
 */
@SpringBootApplication
public class WebApplication2 {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication2.class, args);
    }
}

LoginController.java

package com.yxtycs.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.UUID;

/**
 * @author yuxt
 * @date 2021/4/17
 */
@Controller
public class LoginController {
    protected final Logger logger = LoggerFactory.getLogger(LoginController.class);
    enum resInfo {
        suc200(200, "操作成功!"), err400(400, "操作失败!"),
        err401(401, "权限认证失败!"), err500(500, "服务器错误!"),
        err555(555, "未知错误!请联系管理员!");
        private final int code;
        private final String msg;
        private resInfo(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }
    }
    private HashMap<String, Object> map = new HashMap<>();
    private int n = 0;
    @PostMapping("/login")
    @ResponseBody
    public HashMap<String, Object> insertLoginInfo(@RequestBody HashMap<String, Object> params, HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        logger.info("get token:" + authorization);
        n = n % 5;
        switch (n) {
            case 0:
                map.put("code", resInfo.suc200.code);
                map.put("msg", resInfo.suc200.msg);
                break;
            case 1:
                map.put("code", resInfo.err400.code);
                map.put("msg", resInfo.err400.msg);
                break;
            case 2:
                map.put("code", resInfo.err401.code);
                map.put("msg", resInfo.err401.msg);
                break;
            case 3:
                map.put("code", resInfo.err500.code);
                map.put("msg", resInfo.err500.msg);
                break;
            default:
                map.put("code", resInfo.err555.code);
                map.put("msg", resInfo.err555.msg);
        }
        return map;
    }

    @GetMapping("/login")
    @ResponseBody
    public HashMap<String, Object> getLoginInfo(@RequestParam HashMap<String, Object> params) {
        HashMap<String, Object> map = new HashMap<>();
        n = n % 5;
        switch (n) {
            case 0:
                map.put("code", resInfo.suc200.code);
                map.put("msg", resInfo.suc200.msg);
                break;
            case 1:
                map.put("code", resInfo.err400.code);
                map.put("msg", resInfo.err400.msg);
                break;
            case 2:
                map.put("code", resInfo.err401.code);
                map.put("msg", resInfo.err401.msg);
                break;
            case 3:
                map.put("code", resInfo.err500.code);
                map.put("msg", resInfo.err500.msg);
                break;
            default:
                map.put("code", resInfo.err555.code);
                map.put("msg", resInfo.err555.msg);
        }
        n++;
        String token = UUID.randomUUID().toString();
        logger.info("set token:" + token);
        map.put("tokenKey", token);
        return map;
    }
}

启动项目,前端报跨域请求错误

xxx from origin xxx has been blocked by CORS policy: Response to preflight request doesn’t pass
在这里插入图片描述

解决方式:参考文章@CrossOrigin详解

或者编写 MvcConfig.java

package com.yxtycs.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * @author yuxt
 * @date 2021/4/17
 */
@Configuration
public class MvcConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }
        };
    }
}

再次启动项目,进行测试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜长思

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值