[Vue+Element-UI] Implement the login registration interface and axios get and post request login functions, and solve cross-domain problems

Table of contents

1. Implement the login and registration interface

1. Preliminary preparation

2. Implementation of login static page

2.1. Create Vue components

2.2. Static page implementation

2.3. Configure routing

2.4. Change App.vue style

2.5. Effect

3. Register static page implementation

3.1. Static page implementation

3.2. Configure routing

3.3. Effect

二、axios

1. Preliminary preparation

1.1. Prepare the project

1.2. Install axios

1.3. Change port

2. GET request

2.1. Import axios

2.2. Write get request

3. POST request

3.1. The difference between get and post

3.2. Import qs

3.3. Write post request

3.4. Optimization processing

3.4.1. Download and install vue-axios

3.4.2. Write api module to add global configuration

3.4.2.1、action.js

3.4.2.2、http.js

3.4.3, main.js configure vue-axios

3.4.3. Use encapsulated axios to send requests

3.4.4. Modified submission event

3. Cross-domain

1. What is a cross-domain issue?

2. Solve cross-domain issues


1. Implement the login and registration interface

1. Preliminary preparation

Build SPA project using vue-cli :

  1. Enter the directory location where you want to create the project
  2. Use the command vue init webpack project name to build a vue project
    vue init webpack element_ui_spa
  3. Use the command npm install element-ui -S to add the Element-UI module
    1. npm install element-ui -S : There is -s after it, they are:
      1. -g : Download node_global global dependencies.
      2. -d : Download the dependency da into the spa project and will not participate in packaging.
      3. -s : Download the dependency da into the spa project and participate in packaging.
  4. Open the project's package.json file to view specific added module information.
  5. Create a views directory in the src directory (this directory is used to store vue components).
  6. Introduce element-ui module into main.js
    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    // 新添加1
    import ElementUI from 'element-ui'
    // 新添加2,避免后期打包样式不同,要放在import App from './App';之前
    import 'element-ui/lib/theme-chalk/index.css'
    
    import App from './App'
    import router from './router'
    
    // 新添加3----实例进行一个挂载
    Vue.use(ElementUI)
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      components: {App},
      template: '<App/>'
    })
    

    At the specified location!!! At the specified location!!! At the specified location!!!---Add three lines of code

2. Implementation of login static page

2.1. Create Vue components

Create our login registration vue component in our src .

2.2. Static page implementation

Set our html style, of course we can also customize it ourselves in the component | Element

<template>
  <div class="Login">
    <el-form class="login-container">
      <h1 class="title">用户登录</h1>
      <el-form-item label="">
        <el-input type="text" v-model="username" placeholder="登录账号" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input type="password" v-model="password" placeholder="登录密码" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" style="width:100%;" @click="doSubmit()">提交</el-button>
      </el-form-item>
      <el-row style="text-align: center;margin-top:-10px">
        <el-link type="primary">忘记密码</el-link>
        <el-link type="primary" @click="gotoRegister()">用户注册</el-link>
      </el-row>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "Login",
  data() {
    return {
      msg: "登录界面",
      username: "",
      password: ""
    }
  },
  methods: {
    gotoRegister() {
      this.$router.push("/Register");
    },
    doSubmit() {

    }
  }
}
</script>

<style scoped>
.login-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding-top: 10%;
  background-image: url(https://pic4.zhimg.com/v2-c5880f5a6d44766feb085c3ae94899c7_r.jpg);
  //background-image: url();
  background-repeat: no-repeat;
  background-position: center right;
  background-size: 100%;
}

.login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}

.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}
</style>

2.3. Configure routing

Modify the default display route of the vue project in router /index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Login from '@/views/Login'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/Login',
      name: 'Login',
      component: Login
    }
  ]
})

2.4. Change App.vue style

Change the original <style> style

<template>
  <div id="app">
    <!--    <img src="./assets/logo.png"><br>-->
    <br>
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
html,
body {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 0px;
  margin: 0px;
}

#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
  widows: 100%;
  height: 100%;
}
</style>

2.5. Effect

3. Register static page implementation

Implement the same operation based on login

3.1. Static page implementation

<template>
  <div class="Register">
    <el-form class="login-container">
      <h1 class="title">用户注册</h1>
      <el-form-item label="">
        <el-input type="text" v-model="username" placeholder="注册账号" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input type="password" v-model="password" placeholder="注册密码" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" style="width:100%;" @click="doSubmit()">提交</el-button>
      </el-form-item>
      <el-row style="text-align: center;margin-top:-10px">
        <el-link type="primary">忘记密码</el-link>
        <el-link type="primary" @click="gotoLogin()">用户注册</el-link>
      </el-row>
    </el-form>
  </div>
</template>
<script>
export default {
  name: "Register",
  data() {
    return {
      msg: "注册界面",
      username: "",
      password: ""
    }
  },
  methods: {
    gotoLogin() {
      this.$router.push("/Login");
    },
    doSubmit() {

    }
  }
}
</script>

<style scoped>
.login-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding-top: 10%;
  background-image: url();
  background-repeat: no-repeat;
  background-position: center right;
  background-size: 100%;
}

.login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}

.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}
</style>

3.2. Configure routing

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Login from '@/views/Login'
import Register from '@/views/Register'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/Login',
      name: 'Login',
      component: Login
    },
    {
      path: '/Register',
      name: 'Register',
      component: Register
    }
  ]
})

3.3. Effect

二、axios

Use the SSM project to build a Java backend, simulate providing an action address for user login, and Vue requests the specified user login interface.

1. Preliminary preparation

1.1. Prepare the project

You need to prepare a project that you have completed yourself, such as SSM projects, maven projects, and SpringMVC projects . If you don’t know how to write, you can refer to my previous blog content spring series_blog of people who cannot self-discipline-CSDN blog .

1.2. Install axios

Enter the CMD window in the project to download. You must enter the CMD window in your project file path .

npm i axios -S

You can see what we downloaded in our package.json

1.3. Change port

Modify the vue project running port in the config /index.js directory

2. GET request

2.1. Import axios

Import the axios we need into the logged in vue file.

import axios from 'axios'

2.2. Write get request

Remember to open your project when testing

//提交事件
    doSubmit() {
      //设置登录访问地址
      let url = "http://localhost:8080/ssm/user/userLogin";
      // 使用json格式进行传值
      let params = {
        username: this.username,
        password: this.password
      }
//get请求
      axios.get(url, {params: params}).then(r => {
        console.log(r);
        if (r.data.success) {//判断success是否为true
          // 为true给一个提示框
          this.$message({
            //message: '登陆成功',
            message: r.data.msg,
            type: 'success'
          });
        } else {
          this.$message({
            //message: '登陆失败',
            message: r.data.msg,
            type: 'warning'
          });
        }

      }).catch(e => {
        // console.log(e);
      });
    }

3. POST request

3.1. The difference between get and post

GET request and POST request are two common HTTP request methods. Their differences are:

  1. Data transmission method : GET requests transmit data through URL parameters, while POST requests transmit data through the request body. The data of the GET request will be appended to the end of the URL and can be seen in the URL address bar , while the data of the POST request will be placed in the request body and will not be exposed in the URL .
  2. Data length limit : Since the data of the GET request is appended to the URL, the length of the URL is limited, generally about 2048 characters. Exceeding this limit will cause the URL to be too long, while the POST request has no clear data length limit.
  3. Security : The parameters of the GET request are appended to the URL in clear text, so it is not suitable for transmitting sensitive information, while the data of the POST request is placed in the request body, which is relatively more secure.
  4. Caching : GET requests can be cached by the browser and can be reused, while POST requests are not cacheable by the browser and require resending the request each time.
  5. Special character processing : GET requests will URL encode special characters, such as spaces, which will be replaced with "%20", while POST requests will not encode special characters.
  6. Idempotence: GET requests are idempotent, that is, multiple identical GET requests will not have side effects on the server , while POST requests are not idempotent, and each POST request may have side effects , such as creating resources or modifying data.

3.2. Import qs

As in the above request, how to import axios, we still import qs.

import qs from 'qs'

3.3. Write post request

The only thing different from the get request is that

  • get:axios.get(url, {params: params}).then(r => {}).catch(e => { });
  • post:axios.get(url,qs.stringify(params)).then(r => {}).catch(e => { });
//提交事件
    doSubmit() {
      //设置登录访问地址
      let url = "http://localhost:8080/ssm/user/userLogin";
      // 使用json格式进行传值
      let params = {
        username: this.username,
        password: this.password
      }
//post请求
      axios.post(url, qs.stringify(params)).then(r => {
        console.log(r);
        if (r.data.success) {//判断success是否为true
          // 为true给一个提示框
          this.$message({
            //message: '登陆成功',
            message: r.data.msg,
            type: 'success'
          });
        } else {
          this.$message({
            //message: '登陆失败',
            message: r.data.msg,
            type: 'warning'
          });
        }

      }).catch(e => {
        // console.log(e);
      });
    }

3.4. Optimization processing

3.4.1. Download and install vue-axios

Download vue-axios in the CMD command window.

3.4.2. Write api module to add global configuration

Create a new api folder in the src directory, and create two files action.js and http.js below .

3.4.2.1、action.js
/**
 * 文件接口地址定义文件
 * 对后台请求的地址的封装,URL格式如下:
 * 模块名_实体名_操作
 */
export default {
  'SERVER': 'http://localhost:8080/ssm', //服务器访问地址
  'SYSTEM_USER_DOLOGIN': '/user/userLogin', //登陆请求
  'SYSTEM_USER_DOREG': '/user/userRegister', //注册请求
  'getFullPath': k => { //获得请求的完整地址,用于mockjs测试时使用
    return this.SERVER + this[k];
  }
}
3.4.2.2、http.js
/**
 * vue项目对axios的全局配置
 */
import axios from 'axios'
import qs from 'qs'

//引入action模块,并添加至axios的类属性urls上
import action from '@/api/action'
axios.urls = action

// axios默认配置
axios.defaults.timeout = 10000; // 超时时间
// axios.defaults.baseURL = 'http://localhost:8080/j2ee15'; // 默认地址
axios.defaults.baseURL = action.SERVER;

//整理数据
// 只适用于 POST,PUT,PATCH,transformRequest` 允许在向服务器发送前,修改请求数据
axios.defaults.transformRequest = function(data) {
	data = qs.stringify(data);
	return data;
};


// 请求拦截器
axios.interceptors.request.use(function(config) {
	return config;
}, function(error) {
	return Promise.reject(error);
});

// 响应拦截器
axios.interceptors.response.use(function(response) {
	return response;
}, function(error) {
	return Promise.reject(error);
});

export default axios;
3.4.3, main.js configure vue-axios

Introduce the api module and vue-axios module into the main.js file

import axios from '@/api/http'                 
import VueAxios from 'vue-axios' 

Vue.use(VueAxios,axios)

3.4.3. Use encapsulated axios to send requests

Remove imported axios and qs modules from Login.vue component

import axios from 'axios'
import qs from 'qs'
3.4.4. Modified submission event
doSubmit() {
      //设置登录访问地址
      let url = this.axios.urls.SYSTEM_USER_DOLOGIN;
      // 使用json格式进行传值
      let params = {
        username: this.username,
        password: this.password
      }
      this.axios.post(url, params).then(r => {
        console.log(r);
        if (r.data.success) {//判断success是否为true
          // 为true给一个提示框
          this.$message({
            message: r.data.msg,
            type: 'success'
          });
        } else {
          this.$message({
            message: r.data.msg,
            type: 'warning'
          });
        }

      }).catch(e => {
      });

    }

4. Implementation of registration function

4.1. Page implementation

Of course, you can define your own page according to your own database and your own needs.

<template>
  <div class="Register">

    <el-form class="login-container">
      <h1 class="title">用户注册</h1>
      <el-form-item label="">
        <el-input type="text" v-model="username" placeholder="输入账号" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input type="password" v-model="password" placeholder="输入密码" show-password autocomplete="off"></el-input>
      </el-form-item>

      <el-form-item label="账号名称" label-width="80px" style="margin-left: 5px;" prop="name">
        <el-input v-model="realname"></el-input>
      </el-form-item>

      <el-form-item label="性别" style="margin-left: 20px;">
        <el-radio-group v-model="sex">
          <el-radio label="1">男</el-radio>
          <el-radio label="2">女</el-radio>
          <el-radio label="3">其他</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="身 份 证" label-width="80px" style="margin-left: 0px;" prop="name">
        <el-input v-model="idcard"></el-input>
      </el-form-item>

      <el-input type="textarea" :rows="2" placeholder="请输入地址" v-model="address">
      </el-input>

      <el-form-item style="margin-top: 30px;">
        <el-button type="primary" style="width:100%;"
                   @click="Register()">注&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;册
        </el-button>
      </el-form-item>
      <el-row style="text-align: center;margin-top:-10px">
        <el-link type="primary">忘记密码</el-link>
        <el-link type="primary" @click="Login()">用户登入</el-link>
      </el-row>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'Register',
  data() {
    return {
      username: "",
      password: "",
      realname: '',
      sex: 0,
      idcard: '',
      address: '',
      msg: '嗨!嗨!嗨!',
      rules: {
        realname: [{
          required: true,
          message: '请输入账号名称',
          trigger: 'blur'
        },
          {
            min: 3,
            max: 18,
            message: '长度在 3 到 18 个字符',
            trigger: 'blur'
          }
        ]
      }
    }

  },
  methods: {
    Login() {
      this.$router.push('/Login');
    },
    Register() {
      let params = {
        username: this.username,
        password: this.password,
        realname: this.realname,
        sex: this.sex,
        idcard: this.idcard,
        address: this.address
      };
      //定义后端都请求地址
      var url = this.axios.urls.SYSTEM_USER_DOREG;
      console.log(params);
      console.log(url);
      //以下是post请求及整合资源
      //通过qs中的stringify方法进行格式转换
      //注意数据是保存到json对象的params属性
      this.axios.post(url, params).then(r => {
        console.log(r);
        //如果携带的参数数据跟后端数据对应正确,说明登入成功,提示
        if (r.data.success) {
          this.$message({
            showClose: true,
            message: r.data.msg,
            type: 'success'
          });
          //注册完成后自动进入登入界面
          this.$router.push('/Login');
        } else {
          //如果携带的参数数据跟后端数据对应错误,说明登入失败,提示
          this.$message.error(r.data.msg);
        }
      }).catch(e => {
        console.log(e);
      });


    }
  }
}
</script>

<style scoped>
.login-wrap {
  padding-top: 30px;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  background-image: url();
  background-repeat: no-repeat;
  background-position: center right;
  background-size: 100%;
}

.login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}

.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}
</style>

4.2. Define interfaces and interface implementation classes

interface

int insertSelective(User record);

Interface implementation

    @Override
    public int insertSelective(User record) {
        return userMapper.insertSelective(record);
    }

4.3. Controller layer

Writing methods in Controller requires a certain foundation of springmvc

 @RequestMapping("/userRegister")
    @ResponseBody
    public JsonResponseBody<?> userRegister(UserVo userVo, HttpServletResponse response) {
        //状态新注册默认为0
        userVo.setStatus("0");
        //因为ID为String类型需要手动设置,当然可以根据自己的需要改为Int类型
        userVo.setId("6");
        int i = userService.insertSelective(userVo);
        if (i > 0) {
            return new JsonResponseBody<>("用户注册完成!快去登入吧!", true, 0, null);
        } else {
            return new JsonResponseBody<>("用户注册失败!重新输入。", false, 0, null);
        }
    }

4.4. Testing

3. Cross-domain

1. What is a cross-domain issue?

        Cross-Origin Resource Sharing (CORS) refers to the fact that on the browser side, due to security policy restrictions, web pages (or Ajax requests) between different sources (domains/protocols/ports) cannot directly interact or access each other. resources . The same-origin policy is a browser security mechanism used to protect user information and prevent malicious attacks.

        The same-origin policy requires that web pages can only interact with resources from the same origin. Origin consists of protocol, domain name, and port number. Browsers block cross-domain requests when the origin is inconsistent. For example, if a web page is running in domain A and attempts to send an AJAX request to domain B through JavaScript, a cross-domain problem will be triggered.

2. Solve cross-domain issues

Write the cross-domain filter CorsFilter2 in your project .

package com.zking.ssm.util;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

/**
 * 配置tomcat允许跨域访问
 * 
 * @author Administrator
 *
 */
public class CorsFilter2 implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

		// Access-Control-Allow-Origin就是我们需要设置的域名
		// Access-Control-Allow-Headers跨域允许包含的头。
		// Access-Control-Allow-Methods是允许的请求方式
		httpResponse.setHeader("Access-Control-Allow-Origin", "*");// *,任何域名
		httpResponse.setHeader("Access-Control-Allow-Headers", "responseType,Origin, X-Requested-With, Content-Type, Accept");
		httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");

		//允许客户端处理一个新的响应头jwt
		//httpResponse.setHeader("Access-Control-Expose-Headers", "jwt,Content-Disposition");
		filterChain.doFilter(servletRequest, servletResponse);
	}

	@Override
	public void destroy() {

	}
}

Add the filter configuration in web.xml, and then my cross-domain problem will be solved.

  <!--CrosFilter跨域过滤器-->
  <filter>
    <filter-name>corsFilter</filter-name>
    <filter-class>com.zking.ssm.util.CorsFilter2</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>corsFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

That’s it for my sharing, everyone is welcome to discuss in the comment area! ! !

Guess you like

Origin blog.csdn.net/weixin_74383330/article/details/133181213