问题:axios访问后端数据导致的跨域以及每次访问session不一样
前端部分
我的vue项目创建命令:
vue init webpack project_name
vue项目创建建议和我的一致,这样才能保证项目目录文件一致。
index.js文件如图:
添加如下:
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'api': {
target: 'http://localhost:8088',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},
配置好后如图:
main.js下添加:
import qs from 'qs'
import store from './store'
axios.defaults.baseURL = 'http://localhost:8088/api'
axios.defaults.withCredentials = true
Vue.prototype.$axios = axios
至此前端决定了跨域和session不一致的问题。
后端部分
创建一个config 包,创建MyConfigMvcConfig.java
添加代码如下:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedOrigins("http://localhost:8080")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
至此后端的跨域问题就解决了。
我们都知道有个注解@CrossOrigin 注解可以解决跨域的问题,但这个注解目前只在Get方法上起作用,post上就没用了,所以还是用上面的方法解决跨域的问题。
特殊问题
vue常常搭配element-ui 和axios 使用,axios在请求时默认将数据放入请求体里面,这样后端接受数据时只能通过注解@RequestBody ,比较麻烦,不能直接在像在传表单数据那样在方法形参的形式获取,这个问题主要针对的是POST请求。
在main.js添加如下代码解决以上的问题:
import qs from 'qs'
axios.interceptors.request.use((config) => {
if (config.method === 'post' && !config.url.includes('upload')) {
config.data = qs.stringify(config.data)
config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
}
return config
}, (error) => {
return Promise.reject(error)
})
上面的代码的功能axios拦截器修改请求头,代码比较简单,但是可以看到上面同时判断了url是不是包含upload请求,这是因为我用element-ui自带组件upload组件时出现了bug,后端形参反而接受不到数据,所以这里判断了下如果包含upload就使用默认的传参方式。
对应的upload代码如下:
<template>
<el-upload
:with-credentials="true"
:http-request="upload"
action=""
multiple
:limit="1"
:on-exceed="handleExceed"
:before-remove="beforeRemove"
ref="upload"
:file-list="fileList">
<el-button type="primary">点击上传</el-button>
</el-upload>
</template>
<script>
export default {
props: ['parentId'],
data () {
return {
fileList: []
}
},
methods: {
handleExceed (files, fileList) {
this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`)
},
upload (param) {
const formData = new FormData()
formData.append('file', param.file)
formData.append('id', this.parentId)
const url = '/admin/upload'
this.$axios.post(url, formData
).then(resp => {
this.$refs.upload.clearFiles()
this.$emit('onUpload')
}).catch(resp => {
console.log('上传失败')
})
}
}
}
</script>
|