介绍
在之前的博文 Spring Boot+Vue项目学习总结 https://blog.csdn.net/xinxin_2011/article/details/86742160 中只是提到了前后端分离的测试代码,并没有详细分析其如何实现的跨域访问,在本篇文章里面就来详细分析一下。
Vue实现跨域访问
首先回忆下登录页面的代码,BlogLogin.vue文件:
<template>
...
<div>
用户名:<input type="text" v-model="loginInfoVo.username" placeholder="请输入用户名" />
<br/>
密码:<input type="password" v-model="loginInfoVo.password" placeholder="请输入密码" />
<br/>
<button v-on:click="login">登录</button>
export default {
name: 'BlogLogin',
...
data () {
return {
loginInfoVo: { username: '', password: '' },
responseResult: []
}
},
methods: {
login () {
this.$axios
.post('/login', {
username: this.loginInfoVo.username,
password: this.loginInfoVo.password
})
.then(successResponse => {
this.responseResult = JSON.stringify(successResponse.data)
if (successResponse.data.code === 200) {
this.$router.replace({path: '/index'})
}
})
.catch(failResponse => {})
}
}
data里面创建了两个变量loginInfoVo和responseResult,loginInfoVo与输入框关联,而变量responseResult用来接收服务器返回的数据。
这里面的登录需要后台的支持,由于前后端分离,这里涉及到跨域访问,所以主入口main.js文件要添加axios支持:
// 引用axios,并设置基础URL为后端服务api地址
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8443/api'
// 将API方法绑定到全局
vue.prototype.$axios = axios
然后在配置文件config/index.js里添加跨域支持代码:
// 路由接口代理配置proxyTable: {
'/api': { target: 'http://localhost:8443', changeOrigin: true, pathRewrite: {
'^/api': ''
}
}
}
这样写之后,在进行ajax请求时,凡是地址中任何以/api开头的请求地址都被解析到目标地址(http://localhost:8443),即target就是你想要的后台接口地址。当然这里面的api也可以替换为其他的路径,只要前后端一致就可以了。回过头再看BlogLogin.vue文件:
<button v-on:click="login">登录</button>
...
methods: {
login () {
this.$axios
.post('/login', {
username: this.loginInfoVo.username,
password: this.loginInfoVo.password
})
当点击登录按钮时执行login (),this.$axios在main.js文件中已经设置为’http://localhost:8443/api’ 了,因此这里访问的就是http://localhost:8443/api/login 地址,后端只要有相应的处理方法就可以了。
那么前端访问时,如何让页面直接跳转到登录页的呢?这就是路由器的功劳,看router/index.js文件:
export default new Router({
routes: [
{
path: '/',
redirect: '/login'
},
{
path: '/index',
name: 'BlogIndex',
component: BlogIndex
},
{
path: '/manage',
redirect: '/login'
},
{
path: '/login',
name: 'BlogLogin',
component: BlogLogin
}
对应访问根地址/的请求直接重定向到/login地址了,而/login对应的就是BlogLogin登录页面了。
另外页面访问时总有个#号,看着很不爽:
如何去掉呢,在路由配置的router/index.js文件添加一句话就可以解决:
再访问就没有讨厌的#了,看着舒服多了:
对于跨域访问,还需要后端支持的。Spring Boot里面Controller方法设置跨域注解就可以了:
Spring Boot就是这么简单,要是使用SpringMVC就得自己写拦截器进行配置了,道理和下面要讲的Go语言框架Gin实现跨域访问是类似的。
Gin支持跨域访问
如果后端函数不支持跨域访问的话,前端会报错:
比如我上一篇博文 我总结的Mac下搭建go开发环境 https://blog.csdn.net/xinxin_2011/article/details/87206538 如果用这个前端进行登录访问,就会报上面的错误。
那如何解决这个跨域问题呢?需要用到gin的中间件方式,先编写一个处理跨域访问的中间件处理函数:
// 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
// 放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
}
然后在处理跨域访问的路由上面注册这个中间件就可以了:
r := gin.Default() // Default routes
...
// group: api
api := r.Group("/api")
{
api.Use(Cors())
...
}
这样就可以跨域登录了。后端代码可以根据喜好在Go和Java中随时切换,而前端的Vue代码不需要任何变动,由此可见前后端分离的优势了吧。