用cros解決前後端分離的跨域問題
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); } returnAjaxResult.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>
效果:
資料成功查出,前後臺分離跨域