前端:使用Vue+axios+elemenet框架实现
后端:SpringBoot+Mybatis
利用 Vue CLI(或写成 vue-cli,即 Vue 脚手架)搭建项目
npm install -g vue-cli
或者
npm install -g @vue/cli
博主直接使用spring网站配置的spring工程,直接使用idea打开运行。
后端运行效果(这个是正常运行的标志,虽然还没有加前端)
java/demo/src/main/java/com/example/demo/User.java
这个类是有问题的!!!解决方法在后面
package book;
public class User {
int ID;
String userame;
String passWord;
public int getId() {
return ID;
}
public void setId(int id) {
this.ID = id;
}
public String getuserName() {
return userame;
}
public void setuserName(String userName) {
this.userame = userName;
}
public String getPassword() {
return passWord;
}
public void setPassword(String password) {
this.passWord = password;
}
}
java/demo/src/main/java/com/example/demo/LoginController.java
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
@Controller
public class LoginController {
@CrossOrigin(origins = "*", allowedHeaders = "*")
@PostMapping(value = "/api/login")
@ResponseBody
public Result login(@RequestBody User requestUser) {
String username = requestUser.getUsername();
if (!Objects.equals("admin", username) || !Objects.equals("123123", requestUser.getPassword())) {
String message = "账号密码错误";
return new Result(400);
} else {
return new Result(200);
}
}
@CrossOrigin
@PostMapping(value = "/api/test")
public int test() {
return 400;
}
}
java/demo/src/main/resources/application.properties添加 内容(初始应该是空白的,后期还要配置数据库等)
server.port=8888
后端创建完成,需开发一个前端显示界面。
登录页面:src\components\Login.vue
<template>
<div>
用户名:<input type="text" v-model="loginForm.username" placeholder="请输入用户名"/>
<br><br>
密码: <input type="password" v-model="loginForm.password" placeholder="请输入密码"/>
<br><br>
<button v-on:click="login">登录</button>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {
loginForm: {
username: '',
password: ''
},
responseResult: []
}
},
methods: {
login () {
this.$axios
.post('/login', {
username: this.loginForm.username,
password: this.loginForm.password
})
.then(successResponse => {
if (successResponse.data.code === 200) {
this.$router.replace({path: '/index'})
}
})
.catch(failResponse => {
})
}
}
}
</script>
跳转页面:src\components\AppIndex.vue
<template>
<div>
Hello World!
</div>
</template>
<script>
export default {
name: 'AppIndex'
}
</script>
<style scoped>
</style>
src\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'
import App from './App'
import router from './router'
import axios from 'axios'
// 设置baseURL,8888是后端端口号,前端请求默认发送到baseURL的地址
// var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8888/api'
Vue.prototype.$axios = axios// 全局注册,其他组件中通过调用 this.$axios 发送数据
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
这儿会报错:
ailed to compile with 1 errors 上午11:32:03
This dependency was not found:
* axios in ./src/main.js
To install it, you can run: npm install --save axios
Error from chokidar (D:\): Error: EBUSY: resource busy or locked, lstat 'D:\DumpStack.log.tmp'
Error from chokidar (D:\node_modules): Error: EBUSY: resource busy or locked, lstat 'D:\DumpStack.log.tmp'
这儿英文提示的很清楚,需安装axios。
src\router\index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Login from '@/components/Login'
import AppIndex from '@/components/AppIndex'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/AppIndex',
name: 'AppIndex',
component: AppIndex
}
]
})
config\index.js
修改proxyTable
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://localhost:8888',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},
同时运行前端和后端项目,访问 localhost:8080/#/login
,输入用户名 admin
,密码 123123
Access to XMLHttpRequest at 'http://localhost:8888/api/login' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
xhr.js:264
POST http://localhost:8888/api/login net::ERR_FAILED
? 这是常见的跨域资源共享(CORS)问题 。
? 浏览器限制了跨域请求,只有在服务端设置了响应头 Access-Control-Allow-Origin 时,才允许跨域请求。 这个错误是由于浏览器的跨域安全策略导致的。
跨域资源共享(CORS)是一种机制,是W3C标准。它允许浏览器向跨源服务器,发出XMLHttpRequest或Fetch请求。整个CORS通信过程都是浏览器自动完成的,不需要用户参与。
CORS的工作原理是:
CORS的配置通常包括以下几个字段:
需要注意的是,使用CORS的前提是浏览器必须支持这个功能,并且服务器端也必须同意这种"跨域"请求。因此实现CORS的关键是服务器。
将这几个类直接改到DemoApplication包下。
如图:
博主的问题是把LoginController类、Result类、User类都放到自己创建的book目录下了。途中的book目录已经删除。book目录需时demo的子目录。
遇到跨域问题的同学可以尝试检查一下自己的
control类所在的包需符合“controller类必须是Application的所在包的类或者子包的类” ,启动类Application是Controller文件的上一级,只有这样,项目启动时才能扫描加载到controller类。
两个页面单独登录可以登录
http://localhost:8080/#/login
http://localhost:8080/#/index
输入用户密码,页面不跳转
单独页面都可以登录说明页面没有问题;
输入用户名密码,在login函数中,修改返回结果都是200后。页面可以正常跳转。说明前端代码正常。
public Result login(@RequestBody User requestUser) {
String username = requestUser.getUsername();
if (!Objects.equals("admin", username) || !Objects.equals("123123", requestUser.getPassword())) {
String message = "账号密码错误";
return new Result(200);
} else {
return new Result(200);
}
}
在方法中打断点,查看变量,username获取为空,密码是正确的。
按照原来的逻辑,应该返回new Result(400)
,确实不会跳转。
检查发现
设置两个断点,一个是setUserName
函数,一个是setPassword
函数。结果只进入setPassword
点击右上角警告提示
警告已经写了这两个函数未使用,那么直接修改名称。修改名称后,还是不跳转。修改函数setUserName
改成setUsername
。此处犯了两个拼写错误,都是泪。
至此完成前后端正常登录跳转功能。
演示结果:
为空,密码是正确的。
按照原来的逻辑,应该返回new Result(400)
,确实不会跳转。
检查发现
设置两个断点,一个是setUserName
函数,一个是setPassword
函数。结果只进入setPassword
点击右上角警告提示
警告已经写了这两个函数未使用,那么直接修改名称。修改名称后,还是不跳转。修改函数setUserName
改成setUsername
。此处犯了两个拼写错误,都是泪。
至此完成前后端正常登录跳转功能。
演示结果: