1.使用的框架:spring+springmvc+mybatis,前端使用Vue,spring版本使用4.2以上版本
<!-- spring版本号 --> <spring.version>4.2.5.RELEASE</spring.version> <!-- mybatis版本号 --> <mybatis.version>3.2.1</mybatis.version>
2.在controller类上加注解@CrossOrigin
@CrossOrigin//跨域问题 @Controller @RequestMapping("/department") public class DepartmentController implements BaseController<Department>{ @Autowired private IDepartmentService departmentService; /** * 添加或者修改 * @param department * @return */ @RequestMapping(method = RequestMethod.PUT) @ResponseBody @Override public AjaxResult addOrUpdate(@RequestBody Department department) { try { if(department.getId()==null){ departmentService.add(department); }else{ departmentService.update(department); } return AjaxResult.me(); } catch (Exception e) { e.printStackTrace(); return AjaxResult.me().setSuccess(false).setMessage("操作失败" + e.getMessage()); } }
加上此注解后,部分版本就可以跨域了,但我的不行,报错500,说我的代码有问题。其实 只要将报错的属性设置到response头部,即可解决此问题,所以我们只要提供一个过滤器或者一个拦截全部的AOP即可解决此问题 代码如下:
第一种:新建一个CrossFilter类实现Filter这个类
import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class CrossFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; //如果要做细的限制,仅限某域名下的可以进行跨域访问到此,可以将*改为对应的域名。 response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "*"); response.setHeader("Access-Control-Max-Age", "1728000"); response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); // response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); chain.doFilter(req, res); } public void init(FilterConfig filterConfig) {} public void destroy() {} }
第二种:使用AOP
//证明是一个配置文件(使用@Component也可以,因为点入后会发现@Configuration还是使用了@Component)
@Configuration
//证明是一个切面
@Aspect
public class ControllerAOP {
//环绕aop
//execution表达式 此表达式表示扫描controller下所有类的所有方法都执行此aop
@Around("execution (* com.beyondli.controller..*.*(..))")
public Object testAop(ProceedingJoinPoint pro) throws Throwable {
//获取response
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
//核心设置
response.setHeader("Access-Control-Allow-Origin", "*");
//执行调用的方法
Object proceed = pro.proceed();
return proceed;
}
}
前端使用的是Vue:
<template> <section> <!--工具条--> <el-col :span="24" class="toolbar" style="padding-bottom: 0px;"> <el-form :inline="true"> <el-form-item> <el-input placeholder="关键字"></el-input> </el-form-item> <el-form-item> <el-button type="primary" >查询</el-button> </el-form-item> <el-form-item> <el-button type="primary" @click="add">新增</el-button> </el-form-item> </el-form> </el-col> <!--表--> <el-table :data="departments" v-loading="listLoading" highlight-current-row style="width: 100%;"> <!--多选框--> <el-table-column type="selection" width="55"> </el-table-column> <!--索引值--> <el-table-column type="index" width="60"> </el-table-column> <!--其他都设置值,只有一个不设置值就自动适应了--> <el-table-column prop="name" label="名称"> </el-table-column> <el-table-column label="操作" width="150"> <template scope="scope"> <el-button size="small" @click="edit(scope.row)">编辑</el-button> <el-button type="danger" size="small" @click="del(scope.row)">删除</el-button> </template> </el-table-column> </el-table> <!--添加或编辑对话框--> <el-dialog title="添加或修改" v-model="formVisible" :close-on-click-modal="false"> <el-form :model="department" label-width="80px" :rules="formRules" ref="department"> <el-form-item label="名称" prop="name"> <el-input v-model="department.name" auto-complete="off"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click.native="formVisible = false">取消</el-button> <el-button type="primary" @click="save" >提交</el-button> </div> </el-dialog> </section> </template> <script> export default { data() { return { formVisible:false,//对话框默认不显示 listLoading:false, departments:[], //初始值 department:{ id:null, name:'' }, formRules: { name: [ { required: true, message: '请输入名称', trigger: 'blur' } ] } } }, methods: { save(){ this.$refs.department.validate((valid) => { //校验 if (valid) { this.$confirm('确认提交吗?', '提示', {}).then(() => { //拷贝对象 let para = Object.assign({}, this.department); //addorupdate this.$http.put("/department",para).then((res) => { this.$message({ message: '操作成功!', type: 'success' }); this.$refs['department'].resetFields(); this.formVisible = false; this.getDepartments(); }); }); } }) }, edit(row){ //回显 let depart = Object.assign({}, row); this.department = depart; //里面本来就有id,相当于回显了id //显示 this.formVisible =true; }, add(){ //清空数据 this.department={ id:null, name:'' } //打开dialog this.formVisible =true; }, getDepartments(){ //发送Ajax请求后台获取数据 axios let para = {}; this.listLoading = true; //显示加载圈 this.$http.patch("/department",para) .then(result=>{ console.log(result); console.log(result.data); this.departments = result.data; this.listLoading = false; //关闭加载圈 }); }, del(row){ console.log(row); this.$confirm('确认删除该记录', '提示', { type: 'warning' }).then(() => { var id = row.id; this.listLoading = true; this.$http.delete("/department/"+id) .then(result=>{ this.listLoading = false; //提示 if(result.data.success){ this.$message({ message: '删除成功', type: 'success' }); }else{ this.$message({ message: result.data.message, type: 'error' }); } //刷新数据 this.getDepartments(); }) }); } }, mounted() { this.getDepartments() } } </script> <style scoped> </style>
效果:
数据成功查出,前后台分离跨域成功