关于跨域:在实际开发过程当中,发现跨域问题并非那么好解决的 由于Springboot安全控制框架使用了Securtiy,它的身份认证基于 JSESSIONID 而axios框架默认是不发送cookie的,所以须要在axios配置中添加javascript
axios.defaults.withCredentials = true
然而由于跨域策略问题,Springboot后端跨域设置也要修改css
@Configuration public class CorsConfig { /** 容许任何域名使用 容许任何头 容许任何方法(post、get等) */ private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); // addAllowedOrigin 不能设置为* 由于与 allowCredential 冲突 corsConfiguration.addAllowedOrigin("http://localhost:9528"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); // allowCredential 需设置为true corsConfiguration.setAllowCredentials(true); return corsConfiguration; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } }
前情概述: 上一篇写了SpringBoot服务端的搭建,总体而言与大部分SpringBoot入门的教程同样,只是添加了一些本身的理解,毕竟开发的时候老是但愿有一个本身用起来顺手的模板。这篇总结的是用vue-cli搭建一个前端脚手架,并经过手工整合放进SpringBoot项目中,实际生产环境极可能整合方式不同,最后使用vue全家桶搭一个登录实例(没有美化UI)
声明:我不是专业前端,因此前端代码可能有些丑,请注重搭建思路,不要在乎代码风格!html
吐槽请忽略 前端博文写了一天,一直没有很好的思路,由于整合框架比较多各个内容关联度又很高,介绍详细了会变成入门大杂烩,因此决定换个思路,只分享一下整合思路,登录实例就只放源代码了,代码内都有一些详细的注释,ES6的语法很花哨(我是java开发人员,ES6语法真的就很花哨)请慢慢研究。抱歉前端
参见上一篇博文 先后端分离 Spring Boot + Vue 开发单页面应用 我的总结(一)vue
# -g 安装在全局 registry指定国内下载地址 $ npm install cnpm -g --registry=https://registry.npm.taobao.org
npm 与 cnpm 基本等价,可是不多状况下cnpm也许有些bug,因此请斟酌使用。java
$ npm install vue-cli -g $ npm install vue -g
打开命令行,进入到你的工做空间,咱们使用vue脚手架来搭建项目node
# 建立一个基于 webpack 模板的新项目 $ vue init webpack vue-springboot-demo # 建立过程会要求你的项目起名之类,基本直接回车确认就能够 $ cd vue-springboot-demo $ cnpm install $ npm run dev
访问页面 localhost:8080 出来页面了就算成功了,Ctrl + C y确认退出webpack
vue-cli 为咱们建立了一个前端工程,咱们能够在此基础上进行拓展
大部分开过vue教程的同窗都知道ios
$ npm run build
能够打包工程,编译后的文件通常在 项目目录/dist 下,这些都是能够发布的版本
vue-cli 建立的项目默认编译后是部署在服务器上的,但若是我想直接放进SpringBoot项目里,就须要一些额外的配置。关于项目开发的配置,通常放置在config下的index.js文件中,好比修改启动的端口等。 config/index.js 省略部分配置git
'use strict' // ... module.exports = { dev: { //... // 开发环境启用的主机 host: 'localhost', // can be overwritten by process.env.HOST // 开发环境启用的端口 port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined //... }, build: { // 将index.htlm 指定生成在dist下 index: path.resolve(__dirname, '../dist/index.html'), assetsRoot: path.resolve(__dirname, '../dist'), // 指定静态文件 js/css等与index平级 assetsSubDirectory: './', // 指定引用地址为相对地址,这样生成的文件就能够直接打开了 // 若指定为 '/' 表明是根目录地址,属于能够发布在单独服务器上的 assetsPublicPath: './', //... } }
修改完配置以后
npm run build
在dist下生成的文件就是咱们须要的内容了,目录结构大体是这样的
双击 index.httml ,页面能够被直接打开,这就是编译后的静态文件了。 还记得第一篇文章咱们为项目建的临时主页吗?是时候换个更漂亮的了。把dist下全部文件copy,而后粘贴在SpringBoot项目resources/static文件夹下,启动SpringBoot项目,访问
这种属于手工整合方式,对于我的开发仍是比较方便的,毕竟最后咱们只须要在SpringBoot导出一个jar包就能够部署了,而企业天然有本身的部署方式。 由于我是后端,在学完Vue教程后,一直不懂dist下的文件怎么使用,甚至觉得要在SpringBoot项目中建立工程,后来终于尝试出来了,特此整理。
前端工程建立以后,要怎么写就是本身的事情了,我准备了一个特别丑的Demo,主要记录一些Vue全家桶整合方式,及先后端ajax通讯配置
使用 IDEA 打开项目,解放生产力,安装Vue.js插件能更进一步解放生产力,记得把项目js模式设置为ES6(会有提示)
简单介绍一下项目依赖
安装一下项目依赖
# i 是install的简写 --save表明在生产环境中使用 $ cnpm i vuex babel-polyfill element-ui axios --save # vue-router可能在初始化的时候就已经安装了 $ cnpm i vue-router --save
最后咱们的package.json 大体是这样子的,完整请在源码中看
{ "name": "vue-springboot-demo", "version": "1.0.0", "description": "A Vue.js project", "author": "做者", //. "private": true, "scripts": { //...略 }, "dependencies": { "axios": "^0.17.1", "babel-polyfill": "^6.26.0", "element-ui": "^2.0.8", "vue": "^2.5.2", "vue-router": "^3.0.1", "vuex": "^3.0.1" }, "devDependencies": { //...开发时依赖的工具 } }
写到这里,咱们来改造一下目录结构,改形成本身喜欢的样子
首先看src根目录下的内容
router 和 store 和 axios 文件夹下分别新建一个 index.js 用于配置路由和状态管理及ajax框架,能够是空文件,具体内容后面讲解
而后是main.js,它会随着首页一块儿加载,一般是整个网页的入口代码,用它来引入模块是最好的。
import Vue from 'vue' // 加载App.vue 组件 import App from './App.vue' // 引入router配置文件 import router from './router' // 引入ElementUI,可使用其组件 import ElementUI from 'element-ui' // css文件需手动引入 import 'element-ui/lib/theme-chalk/index.css' // 引入vuex配置文件 import store from './store' // 引入ajax框架axios配置 import axios from './axios' // 设置 Vue.config.productionTip = false 来关闭生产模式下给出的提示 Vue.config.productionTip = false // 表明使用ElementUI组件 Vue.use(ElementUI) // 将axios挂载到Vue原型上方便调用 Vue.prototype.$ajxj = axios /* eslint-disable no-new */ new Vue({ el: '#app', router, store, template: '<App/>', components: { App } })
App.vue ,.vue后缀名的文件是Vue提供的单文件组件方式单文件组件 核心由template标签组成,script标签能够挂载Vue实例等脚本,造成组件,style标签能够用来写css。 由于本人作页面水平有限,前端Demo作得很是丑,主要是记录是各个模块的配置,敬请谅解!
<template> <!-- 这里的Html写的比较丑,是(技术有限)为了布局结构更清晰一些 --> <div id="app" style="height:600px"> <!-- element的布局 v-if:根据返回值决定是否渲染 --> <el-container v-if="isLogin" class="main-container" > <el-header > <!-- header组件 --> <Header></Header> </el-header> <el-container> <!-- 导航组件 --> <Nav></Nav> <el-main> <!-- 这里放置的是路由的页面 --> <router-view></router-view> </el-main> </el-container> </el-container> <!-- 登录组件,v-if:根据返回值决定是否渲染 --> <Login v-if="!isLogin"></Login> </div> </template> <script> import Nav from './components/nav.vue' import Header from './components/header.vue' import Login from './pages/login.vue' export default { components: { // ES6简写语法 Nav:Nav Nav, Header, Login }, name: 'app', computed: { isLogin () { // 读取全局状态,获取用户是否登录,决定渲染状态 return this.$store.state.login.isLogin } } } </script> <style> #app { font-family: Helvetica, sans-serif; text-align: center; } .main-container { height: 100%; border: 1px solid #eee; margin: 10px 50px 0 50px; } /* 加上红色边框看出布局 */ .el-container, .el-aside { border: 1px solid red; } </style>
吐槽,博客的markdown文本编辑code部分常常会有bug,上面那段我改不过来格式了,请参照源码
剩下的源码我就不贴在文章中了,登录实例大量参考 git传送门 thaks again!
这里重点讲经过axios与SpringBoot服务器通讯会遇到两个问题
// 设置content-type // 这里处理的是 针对SpringMVC Controller 没法正确得到请求参数的问题 axios.interceptors.request.use( config => { let data = config.data let key = Object.keys(data) // 重写data,由{"name":"name","password":"password"} 改成 name=name&password=password config.data = encodeURI(key.map(name => `${name}=${data[name]}`).join('&')) // 设置Content-Type config.headers = { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' } return config }, error => { return Promise.reject(error) } )
之后可能完善,谢谢。