笔记-一天搞定Spring+Vue全栈开发
一天搞定Spring+Vue全栈开发
参考&学习视频
此为b站视频的笔记。什么?原视频在哪里?
源链接如下:
视频和笔记内容都会涵盖:
JaveEE企业级框架:SpringBoot+MybatisPlus
Web前端核心框架:Vue+ElementUI
公共云部署:前后端项目集成打包与部署
值得一提的是,Typora的内存占用确实好小()直接开夸好吧
P1 课程介绍及环境准备
Web技术基础
目前市面上的主要软件可分为两种:
BS(Browser/Server,浏览器/服务器架构模式)
CS(Client/Server,客户端/服务器架构模式)
C/S架构的主要特点为交互性较强,具有安全访问模式,网络流量低,响应速度快。因为客户端负责大多数业务逻辑和UI演示,所以也被成为胖客户端,C/S结构的软件需要针对不同的操作系统开发不同版本的软件。
随着互联网的兴起,CS架构不适合Web,最大的原因是Web应用程序的修改和升级非常迅速,而CS架构需要每个客户端逐个升级桌面App,因此,Browser/Server模式开始流行,简称BS架构。
B/S架构的主要特点是分散性高,维护方便,开发简单,共享性高,总拥有成本低。
在BS架构下,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端,浏览器只需要请求服务器,获取Web页面,并把Web页面展示给用户即可。
Maven
Maven是一个项目管理工具。可以对Java项目进行自动化的构建和依赖管理
Maven的作用可以分为三类:
项目构建:提供标准的,跨平台的自动化构建项目的方式
依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突等问题
统一开发结构:提供标准的,统一的项目开发结构,如下图所示:
Maven仓库
运行Maven的时候,Maven所需要的任何构建都是直接从本地仓库获取的。如果本地仓库没有,它会首先尝试从远程仓库下载构建至本地仓库。
P2 SpringBoot快速上手
SpringBoot介绍
Spring Boot是由Pivotal团队提供的基于Spring的全新框架,旨在简化Spring应用的初始搭建和开发过程。
Spring Boot是所有基于Spring开发项目的起点。
Spring Boot就是尽可能地简化应用开发的门槛,让应用开发、测试、部署变得更加简单。
SpringBoot特点
遵循“约定优于配置”的原则,只需要很少的配置或使用默认的配置。
能够使用内嵌的Tomcat、Jetty服务器、不需要部署war文件。
提供定制化的服务器Starters,简化Maven配置,开箱即用。
纯Java配置,没有代码生成,也不需要XML配置。
提供了生产级的服务监控方案,如安全监控、应用监控、健康检测等。
快速创建SpringBoot应用
利用Idea提供的Spring Initializr创建SpringBoot应用
填写项目信息:
Group:一般输入公司域名
Artifact:项目名称
开发环境热部署
在实际的项目开发调试过程中会频繁地修改后台类文件,导致需要重新编译、重新启动,整个过程非常麻烦,影响开发效率。
Spring Boot提供了spring-boot-devtools组件,使得无须手动重启SpringBoot应用即可重新编译、启动项目,大大缩短编译启动的时间。
devtools会监听classpath下的文件变动,出发Restart类加载器重新加载该类,从而实现类文件和属性文件的热部署。
并不是所有的更改都需要重启应用(如静态资源、视图模板),可以通过设置spring.devtools.restart.exclude属性来指定一些文件或目录的修改,不用重启应用。
在pom.xml配置文件中添加dev-tools依赖。
使用optional=true表示依赖不会传递,即该项目依赖devtools;其他项目如果引入此项目生成的JAR包,则不会包含devtools。
1
2
3
4
5<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>在application.properties中配置devtools。
1
2
3
4
5
6# 热部署生效
spring.devtools.restart.enabled=true
# 设置重启目录
spring.devtools.restart.addtional-paths=src/main/java
# 设置classpath目录下的WEB-INF文件夹内容修改不重启
spring.devtools.restart.exclude=static/**
如果使用了Eclipse,那么在修改完代码并保存之后,项目将自动编译并触发重启,而如果使用了IntelliJ IDEA,还需要配置项目自动编译。
打开Settings页面,在左边的菜单栏依次找到Build,Execution,Deployedment->Complie,勾选Build project automatically
按Ctrl+Shift+Alt+/快捷键调出Maintenance界面,单击Registry,勾选compiler,automake,allow.when.app.running复选框
做完这两步配置之后,若开发者再次在IntelliJ IDEA修改代码,则项目会自动重启。
P3 SpringBoot Controller
Web入门
Spring Boot将传统Web开发的mvc、json、tomcat等框架整合,提供了spring-boot-starter-web组件,简化了Web应用配置。
创建SpringBoot项目勾选Spring Web选项后,会自动将spring-boot-starter-web组件加入到项目中。
spring-boot-starter-web启动器主要包括web、webmvc、json、tomcat等基础依赖组件,作用是提供Web开发场景所需的所有底层依赖。
webmvc为Web开发的基础框架,json为JSON数据解析组件,tomcat为自带的容器依赖
1 | <dependency> |
控制器
SpringBoot提供了**@Controller和@RestController**两种注解来标识此类负责接收和处理HTTP请求。
如果请求的是页面和数据,使用@Controller注解即可;如果只是请求数据,则可以用@RestController注解。
@Controller的用法
示例中返回了hello页面和name的数据,在前端页面中可以通过${name}参数获取后台返回的数据并显示。
@Controller通常与Thymeleaf模板引擎结合使用。
所以一般现在都不要Controller注解了,因为前后端目前大部分都是分离的1
2
3
4
5
6
7
8
9
10
public class HelloController{
{
public String index(ModelMap map){
map.addAttribute("name","zhangsan");
return "hello";
}
}
}
@RestController的用法
默认情况下,@RestController注解会将返回的对象数据转换为JSON数据。
1 |
|
路由映射
@RequestMapping注解主要负责URL的路由映射。它可以添加在Controller类或者具体的方法上。
如果添加在Controler类上,则这个Controller中的所有路由映射都将会加上此映射规则,如果添加在方法上,则只对当前方法生效。
@RequestMapping注解包含很多属性参数来定义HTTP的请求映射规则。常用的属性参数如下:
- value: 请求URL的路径,支持URL模板、正则表达式
- method: HTTP请求方法
- consumes:请求的媒体类型(Content-Type),如application/json
- produces: 响应的媒体类型
- params,headers:请求的参数及请求头的值
@RequestMapping的value属性用于匹配URL映射,value支持简单表达式(例:@RequestMapping(“/user”))
@RequestMapping支持使用通配符匹配URL,用于统一映射某些URL规则类似的请求:@RequestMapping(“/getJson/*.json”),当在浏览器中请求/getjson/a.json或者/getJson/b.json时都会匹配到后台的Json方法
@RequestMapping的通配符匹配非常简单实用,支持”*” “?” “**”等通配符。
符号”*”匹配任意字符, 符号”**”匹配任意路径,符号”?”匹配单个字符。
有通配符的优先级低于没有通配符的,比如/user/add.json比/user/*.json优先匹配。
有 “**” 通配符的优先级低于有
通配符的。
Method匹配
HTTP请求Method有GET、POST、PUT、DELETE方式。HTTP支持的全部Method
@RequestMapping注解提供了method参数指定请求的Method类型,包括RequestMethod.GET、RequestMethod.POST、RequestMethod.DELETE、RequestMethod.PUT等值,分别对应HTTP请求的Method
1
2
3
4
public String getData(){
return "hello";
}Methond匹配也可以使用@GetMapping、@PostMapping等注解代替
参数传递
不使用注解的方法
举个例子说明一下,以下为例:
可以在hello方法里传入String参数nickname,在return的时候引用加上:
1 |
|
就可以传入了:
如果传入的参数和浏览器上的名称不一样怎么办?
在方法传参的那里加入@RequestParam(value = “nickname”),这样就会检索其的值赋予到name上面。
1 |
|
其中对于@RequestParam(value = “nickname”),也可以在选择其是不是必须的:
1 |
- true(default):默认为true,必须传入参数,不然会报错。
- false:设置该参数为非必需,是否传入不影响整体的运行。
POST请求
直接post到上具体参数
创建发送POST请求的Test2类
1 |
|
直接post到类
为了上传一个类的数据到url上作为示范,在这里创建User类为例子:
1 | public class User { |
1 |
|
使用JSON的传参到类
@RequestBody User user =>加上**@RequestBody**即可。
1 |
|
P4 SpringBoot文件上传+拦截器
静态资源访问
使用IDEA创建Spring Boot项目,会创建出classpath:/static/目录,静态资源一般放在这个目录下即可。
如果默认的静态资源过滤策略不能满足开发需求,也可以自定义静态资源过滤策略。
在application.properties中直接定义过滤规则和静态资源位置
1
2spring.mvc.static-path-pattern=/static/**
spring.web.resources.static-locations=classpath:/static/过滤规则为/static/**,静态资源位置为classpath:/static/
以此为例:
仅了解即可,一般不会用到 一般都不会去改这个默认路径的。
文件上传原理
- 表单的enctype属性规定在发送到服务器之前应该如何对表单进行数据编码
- 当表单的enctype=“application/x-www-form-urlenconded”(默认)时,form表单中的数据格式为:key=value&value
- 当表单的enctype=“multipart/form-data时”,其传输形式如下
SpringBoot实现上传文件功能
Spring Boot工程嵌入的tomcat限制了请求的文件大小,每个文件的配置最大为1Mb,单次请求的文件总数不能大于10Mb。
要更改这个默认值需要在配置文件(如application.properties)中加入两个配置
1 | spring.servlet.multipart.max-file-size=10MB |
当表单的enctype=”multipart/form-data”时,可以使用MultipartFile获取上传的文件数据,再通过transferTo方法将其写入磁盘中
1 |
|
拦截器
拦截器在Web系统中非常常见,对于某些全局统一的操作,我们可以把它提取到拦截器中实现。总结起来,拦截器大致有以下使用场景:
- 权限检查:如登录检测,进入处理程序检测是否登录,如果没有,则直接返回登陆界面
- 性能监控:有时系统在某段时间莫名其妙很慢,可以通过拦截器在进入处理程序之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间
- 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有提取Locale电话、Theme信息等,只要是多个处理程序都需要的,即可使用拦截器实现。
Spring Boot定义了HandlerInterceptor接口来实现自定义拦截器的实现
HandlerInterceptor接口定义了preHandler、postHandle、afterCompletion三种方法,通过重写这三种方法实现请求前、请求后等操作
拦截器定义
1 | public class LoginInterceptor implements HandlerInterceptor { |
拦截器注册
- addPathPatterns方法定义拦截的地址
- excludePathPatterns定义排除某些地址不被拦截
- 添加的一个拦截器没有addPathPattern任何一个url则默认拦截所有请求
- 如果没有excludePathPatterns任何一个请求,则默认不放过任何一个请求。
1 |
|
P5 RESTful服务+Swagger
RESTful介绍
- RESTful是当前流行的互联网软件服务架构设计风格。
- REST(Representational State Transfer,表述性状态转移)一词是由Roy Thomas Fielding在2000年的博士论文中提出的,它定义了互联网软件服务的架构原则,如果是一个架构符合REST原则,则称之为RESTful架构。
- REST并不是一个标准,它更像一组客户端和服务端交互时的架构理念和设计原则,基于这种架构理念和设计原则的Web API更加简洁,更有层次。
RESTful的特点
- 每一个URI代表一种资源。
- 客户端使用GET、POST、PUT、DELETE四种表示操作方式的动词对服务器端资源进行操作:
- GET用于获取资源
- POST用于新建资源(也可以用于更新资源)
- PUT用于更新资源
- DELETE用于删除资源
- 通过操作资源的表现形式来实现服务端请求操作。
- 资源的表现形式是JSON或者HTML
- 客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都包含必需的信息。
RESTful API
- 符合RESTful规范的Web API需要具备如下两个关键特性:
- 安全性:安全的方法被期望不会产生任何副作用,当我们使用GET操作获取资源时,不会引起资源本身的改变,也不会引起服务器状态的改变。
- 幂等性:幂等的方法保证了重复进行一个请求和一次请求的效果相同(并不是指响应总是相同的,而是指服务器上资源的状态从第一次请求后就不再改变了),在数学上幂等性是指N次变换和一次变换相同。
HTTP Method
HTTP提供了POST、GET、PUT、DELETE等操作类型对某个Web资源进行Create、Read、Update和Delete操作。
一个HTTP请求除了利用URI标注目标资源之外,还需要通过HTTP Method指定针对该资源的操作类型,一些常见的HTTP方法及其在RESTful风格下的使用:
HTTP方法 操作 返回值 特定返回值 POST Create 201(Created),提交或保存资源 404(Not Found),409(Conflict)资源已存在 GET Read 200(OK),获取资源或数据列表,支持分页、排序和条件查询 200(OK)返回资源,404(Not Found)资源不存在 PUT Update 200(OK)或204(No Content),修改资源 404(Not Found)资源不存在,405(Method Not Allowed)禁止使用改方法调用 PATCH Update 200(OK)或204(No Content),部分修改 404(Not Found)资源不存在 DELETE Delete 200(OK),资源删除成功 404(Not Found)资源不存在,405(Method Not Allowed)禁止使用改方法调用
HTTP状态码
- HTTP状态码就是服务向用户返回的状态码和提示信息,客户端的每一次请求,服务都必须给出回应,回应包括HTTP状态码和数据两部分。
- HTTP定义了40个标准状态码,可用于传达客户端请求的结果。状态码分为以下5个类别:
- 1xx:信息,通信传输协议级信息
- 2xx:成功,表示客户端的请求已成功接受
- 3xx:重定向,表示客户端必须执行一些其他操作才能完成其请求
- 4xx:客户端错误,此类错误状态码指向客户端
- 5xx:服务器错误,服务器负责这些错误状态码
SpringBoot实现RESTful API
Spring Boot提供的spring-boot-starter-web组件完全支持开发RESTful API,提供了与REST操作方式(GET、POST、PUT、DELETE)对应的注解。
- @GetMapping:处理GET请求,获取资源。
- @PostMapping:处理POST请求,新增资源。
- @PutMapping:处理PUT请求,更新数据。
- @DeleteMapping:处理DELETE请求,删除资源。
- @PatchMapping:处理PATCH请求,用于部分更新资源。
在RESTful架构中,每个网址代表一种资源,所以URI中建议不要包含动词,只包含名词即可,而且所用的名词往往与数据库的表格名对应。
用户管理模块API示例:
HTTP Method | 接口地址 | 接口说明 |
---|---|---|
POST | /user | 创建用户 |
GET | /user/id | 根据id获取用户信息 |
PUT | /user | 更新用户 |
DELETE | /user/id | 根据id删除对应的用户 |
1 |
|
什么是Swagger
- Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful风格的Web服务,是非常流行的API表达工具。
- Swagger能够自动生成完善的RESTful API文档,同时并根据后台代码的修改同步更新,同时提供完整的测试页面来调试API。
使用Swagger生成Web API文档
- 在Spring Boot项目中集成Swagger同样非常简单,只需在项目中引入springfox-swagger2和springfox-swagger-ui依赖即可。
1 |
|
注意事项
Spring Boot 2.6.X后与Swagger有版本冲突问题,需要在application.properties中加入以下配置:
1 | spring.mvc.pathmatch.matching-strategy=ant_path_matcher |
使用Swagger进行接口测试
启动项目访问 http://127.0.0.1:8080/swagger-ui.html ,即可打开自动生成的可视化界面。
这里我自己进不去,我选择后面使用Springdoc
P6 Mybatis快速上手
ORM介绍
- ORM(Object Relational Mapping,对象关系映射)是为了解决面向对象与关系数据库存在的互不匹配现象的一种技术。
- ORM通过使用描述对象和数据库之间映射的元数据将程序中的对象自动持久化到关系数据库中。
- ORM框架的本质是简化编程中操作数据库的编码。
MyBatis-Plus介绍
- MyBatis是一款优秀的数据持久层ORM框架,被广泛地应用于应用系统。
- MyBatis能够非常灵活地实现动态SQL,可以使用XML或注解来配置和映射原生信息,能够轻松地将Java中的POJO(Plain Ordinary Java Object,普通的Java对象)与数据库中的表和字段进行映射关联。
- Mybatis-Plus是一个Mybatis的增强工具,在Mybatis的基础上做了增强,简化了开发。
添加依赖
1 | <!-- MyBatisPlus依赖 --> |
全局配置
配置数据库相关信息。
1 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource |
添加@MapperScan注解
1 | @SpringBootApplication |
说一下个人在配置中遇到的一些问题( 没脸见人,配置环境研究了半天。最后得出:)
- 如果SpringBoot版本是3.x.x的 需要将mybatis-plus-boot-starter替换为mybatis-plus-spring-boot3-starter
- 配置好pom.xml文件后需要先点击idea的clean,后点击install,最后点击小圆圈(血的教训,忘记点,
呆比)
Mybatis CRUD注解
注解 | 功能 |
---|---|
@Insert | 实现插入 |
@Update | 实现更新 |
@Delete | 实现删除 |
@Select | 实现查询 |
@Result | 实现结果集封装 |
@Results | 可以与@Result一起使用,封装多个结果集 |
@One | 实现一对一结果集封装 |
@Many | 实现一对多结果集封装 |
CRUD操作
1 |
|
但是呢,其实在使用MybatisPlus的话,Mapper的内容就可以不用自己写啦!(上面的内容都是Mybatis的)
经典白学
如果数据库的表名字和你的java项目的不一样,可以通过**@TableName**注解来引导去查询!
1 |
|
更多关于Mybatis-Plus的注解可以在 注解配置 | MyBatis-Plus 上进行查看,这边仅进行一些说明。
P7 MybatisPlus多表查询及分页查询
*没有涉及太多的新内容,类似于知识点拓展
- 多表查询
- 分页查询
多表查询
实现复杂关系映射,可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置。
注解 | 说明 |
---|---|
@Results | 代替 |
@Result | 代替 -column:数据表的字段名称 -property:类中对应的属性名 -one:与@One注解配合,进行一对一的映射 -many:与@Many注解配合,进行一对多的映射 |
@One | 代替 通过select属性指定用于多表查询的方法 使用格式:@Result(column=””,property=”,one=@One(select=””)) |
@Many | 代替 使用格式:@Result(column=””,property=”,one=@One(select=””)) |
分页查询
1 |
|
测试
1 | // 查询所有用户:localhost:8080/findAll |
P8 Vue框架快速上手 && P9 Vue组件化开发
前端环境准备
编码工具:VSCode
依赖管理:NPM
项目构建:VueCli
Vue框架介绍
Vue是一套用于构建用户界面的渐进式框架。
Vue.js提供了MVVM数据绑定和一个可组合的组件系统,具有简单、灵活的API。
其目标是通过尽可能简单的API实现响应式的数据绑定和可组合的视图组件。
MVVM模式
MVVM模式是Model-View-ViewModel的缩写,他是一种基于前端开发的架构模式,其核心是提供对View和ViewModel的双向数据绑定。
Vue提供了MVVM风格的双向数据绑定,核心是MVVM中的VM,也就是ViewModel,ViewModel负责连接View和Model,保证视图和数据的一致性。
Vue快速入门
- 导入vue.js的script脚本文件
1 | <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> |
- 在页面中声明一个将要被vue所控制的DOM区域,即MVVM中的View
1 | <div id="app"> |
- 创建vm实例对象(vue实例对象)
1 | const { createApp, ref } = Vue |
NPM简介
- NPM是一个NodeJS包管理和分发工具
- NPM以其优秀的依赖的管理机制和庞大的用户群体,目前已经发展成为整个JS领域的依赖管理工具
- NPM最常见的用法就是用于安装和管理依赖。要使用NPM,首先要安装Node工具
NodeJS安装
- Node.js是一个基于Chrome V8引擎的 Javascript 运行时环境
- Node包含了NPM包管理工具
- 下载地址:https://nodejs.org/zh-cn/
NPM使用
命令([]中的表示可选) | 说明 |
---|---|
npm init [-y|–yes] | 初始化目录,生成package.json,-y和–yes参数表示所有的选项均选择yes |
npm install | 安装package.json中的所有依赖 |
npm install –production | 安装package.json中dependencies下的依赖 |
npm install |
安装指定依赖 |
npm install |
全局安装指定依赖 |
npm install |
安装指定依赖,并将其记录在devDependencies中 |
npm install |
安装指定依赖,依赖不需要记录到package.json中 |
npm uninstall |
移除指定依赖 |
npm prune | 移除不在package.json却在node_modules中的依赖 |
npm update | 升级全部依赖的版本 |
npm update |
升级指定依赖的版本 |
npm outdated | 查看过期依赖 |
npm list |
查看依赖的当前版本 |
npm search |
搜索包含关键字的依赖 |
npm ls [-g] [–depth=0] | 查看项目中或全部的依赖包,可指定层级为0 |
npm view |
查看依赖信息,包括历史版本:可指定field来查看某个键值;可添加–json参数以json格式显示结果 |
npm home |
在浏览器端打开依赖的主页 |
npm repo |
在浏览器端打开依赖的GitHub地址 |
npm docs |
查看依赖的文档 |
npm bugs |
查看依赖的 bug |
Vue CLI使用
- Vue CLI是Vue官方提供的构建工具,通常成为脚手架
- 用于快速搭建一个带有热重载(在代码修改后不必刷新页面即可呈现修改后的效果)及构建生产版本等功能的单页面应用
- Vue CLI基于webpack构建,也可以通过项目内的配置文件进行配置
- 安装: npm install -g @vue/cli
P10 第三方组件element-ui
教学内容:组件间的传值、element-ui介绍、组件的使用、图标的使用
组件间的传值
- 组件可以由内部的Data提供数据,也可以由父组件通过prop的方式传值。
- 兄弟组件之间可以通过Vuex等统一数据源提供数据共享。
element-ui介绍
- Element是国内饿了么公司提供的一套开源前端框架,简介优雅,提供了Vue、React、Angular等多个版本。
- 文档地址:https://element.elemt.cn/#/zh-CN/
- 安装:npm i element-ui
- 引入Element:
1 | import Vue from 'vue'; |
第三方图标库
- 由于Element UI提供的字体图符较少,一般会采用其他图标库,如著名的Font Awesome
- Font Awesome提供了675个可缩放的矢量图标,可以使用CSS所提供的所有特性对它们进行更改,包括大小、颜色、阴影或者其他任何支持的效果。
- 文档地址:http://fontawesome.dashgame.com/
- 安装:npm install font-awesome
- 使用:import ‘font-awesome/css/font-awesome.min.css’
1 | <i class="fa fa-camera-retro"></i> fa-camera-retro |
P11 Axios网络请求
Axios简介
- 在实际项目开发中,前端页面所需要的数据往往需要从服务器端获取,这必然涉及与服务器的通信。
- Axios是一个基于promise网络请求库,作用于node.js和浏览器中。
- Axios在浏览器端使用XMLHttpRequest发送网络请求,并能自动完成JSON数据的转换。
- 安装:npm install axios
- 地址:https://www.axios-http.cn
发送网络请求
- 发送get请求
1 | //向给定ID的用户发起请求 |
1 | //上述请求也可以按以下方式完成(可选) |
- 发送POST请求
1 | axios.post('/user',{ |
异步回调请求
- async/await
1 | //支持async/await用法 |
其他请求方式
参考:https://axios-http.com/zh/docs/req_config
1 | //发起一个post请求 |
为什么会出现跨域问题
- 为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源,称为同源策略,同源策略是浏览器安全的基石。
- 同源策略(Sameoriginpolicy)是一种约定,它是从浏览器最核心也是最基本的安全功能
- 所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
- 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域,此时无法读取非同源网页的Cookie,无法向非同源地址发送AJAX请求
跨域问题解决
- CORS(Cross-Origin Resource Sharing)是由W3C制定的一种跨域资源共享技术标准,其目的就是为了解决前端的跨域需求。
- CORS可以在不破坏既有规则的情况下,通过后端服务器实现CORS接口,从而实现跨域通信。
- CORS将请求分为两类:简单请求和非简单请求,分别对跨域通信提供了支持。
简单请求
满足以下条件的请求即为简单请求:
- 请求方法:GET、POST、HEAD
- 除了以下的请求头字段以外,没有自定义的请求头:
Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type
- Content-Type的值只有以下三种:
- text/plain、multipart/form-data、application/x-www-form-urlencoded
简单请求的服务器处理
对于简单请求,CORS的策略是请求时在请求头中增加一个Origin字段
1 | Host:localhost:8080 |
服务器收到请求后,根据该字段判断是否允许该请求访问,如果允许,则在HTTP信息中添加Access-Control-Allow-Origin的字段。
1 | Access-Control-Allow-Origin:http:localhost:8081 |
非简单请求
- 对于非简单请求的跨源请求,浏览器在真实请求发出前增加一次OPTION请求,成为预检请求(preflight request)
- 预检请求将真实请求的信息,包括请求方法、自定义头字段、源信息添加到HTTP头信息字段中,询问服务器是否允许这样的操作。
- 例如一个GET请求:
1 | OPTIONS /test HTTP/1.1 |
Access-Control-Request_Method表示请求使用的HTTP方法,Access-Control-Request-Headers包含请求的自定义头字段
服务器收到请求时,需要分别对Origin、Access-Control-Request-Method、Access-Control-Request-Headers进行验证,验证通过后,会在返回HTTP头中添加:
1
2
3
4
5Access-Control-Allow-Origin:http://www.test.com
Access-Control-Allow-Methods:GET,POST,PUT,DELETE
Access-Control-Allow-Headers:X-Custom-Header
Access-Control-Allow-Credentials:true
Access-Control-Max-Age:1278000Access-Control-Request-Methods、Access-Control-Allow-Headers:真实请求允许的方法、允许使用字段
Access-Control-Allow-Credentials:是否允许用户发送、处理cookie
Access-Control-Max-Age:预检请求的有效期,单位为秒,有效期内不会重复发送预检请求。
当预检请求通过后,浏览器才会发送真实请求到服务器。这样就实现了跨域资源的请求访问。
SpringBoot中配置CORS
- 在传统的Java EE开发中,可以通过过滤器统一配置,而Spring Boot中对此则提供了更加简洁的解决方案
1 |
|
也可以在Controller上面加一个 @CrossOrigin 注解,这样就不用添加类了 今典白雪v
与Vue整合
- 在实际项目开发中,几乎每个组件中都会用到axios发起数据请求。此时会遇到如下问题:
- 每个组件中都需要导入axios
- 每次发请求都需要填写完整的请求路径
- 可以通过全局配置的方式解决上述问题:
1 | //配置请求跟路径 |
P12 前端路由VueRouter
VueRouter安装与使用
Vue路由vue-router是官方的路由插件,能够轻松的管理 SPA 项目中组件的切换。
Vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。
vue-router 目前有 3.x的版本和 4.x的版本,vue-router 3.x 只能结合 vue2进行使用,vue-router 4.x 只能结合 vue3 进行使用。
安装:npm install vue-router@4
导航守卫
导航守卫可以控制路由的访问权限。示意图如下:
全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。
你可以使用router.beforeEach注册一个全局前置守卫:
1 | router.beforeEach((to,from,next) => { |
- to :即将要进入的目标
- from:当前导航正要离开的理由
- 在守卫方法中如果声明了next形参,则必须调用next()函数,否则不允许用户访问任何一个路由
- 直接放行:next()
- 强制其停留在当前页面:next(false)
- 强制其跳转到登录页面:next(‘/login’)
此外也可以了解一下参数传递和子路由是什么,在这里因为这俩需要具体例子进行赘述,就不再进行额外笔墨说明了
P13 状态管理VueX
Vuex介绍
- 对于组件化开发来说,大型应用的状态往往跨越多个组件。在多层嵌套的父子组件之间传递状态已经十分麻烦,而Vue更是没有为兄弟组件提供直接共享数据的办法。
- 基于这个问题,许多框架提供了解决方案–使用全局的状态管理器,将所有分散的共享数据交由状态管理器保管,Vue也不例外。
- Vuex 是一个专为 Vue.is 应用程序开发的状态管理库,采用集中式存储管理应用的所有组件的状态。
- 简单的说,Vuex用于管理分散在Vue各个组件中的数据。
- 安装:npm install vuex@next
官网:开始 | Vuex
状态管理
- 每一个Vuex应用的核心都是一个store,与普通的全局对象不同的是,基于Vue数据与视图绑定的特点,当store中的状态发生变化时,与之绑定的视图也会被重新渲染。
- store中的状态不允许被直接修改,改变store中的状态的唯一途径就是显式地提交(commit)mutation,这可以让我们方便地跟踪每一个状态的变化。
- 在大型复杂应用中,:如果无法有效地跟踪到状态的变化,将会对理解和维护代码带来极大的困扰。
- Vuex中有5个重要的概念:State、Getter、Mutation、Action、Module.
State
State用于维护所有应用层的状态,并确保应用只有唯一的数据源
1 | //创建一个新的 store 实例 |
在组件中,可以直接使用this.$store.state.count访问数据,也可以先用mapState辅助函数将其映射下来
1 | //在单独构建的版本中辅助函数为 Vuex.mapstate |
Getter
Getter维护由State派生的一些状态,这些状态随着State状态的变化而变化
1 | const store =createstore({ |
Action
- Action类似Mutation,不同在于:
- Action不能直接修改状态,只能通过提交mutation来修改,Action可以包含异步操作
1 | const store =createStore({ |
P14 前端数据模拟MockJS
mockjs介绍
Mock.js 是一款前端开发中拦截Ajax请求再生成随机数据响应的工具,可以用来模拟服务器响应。
优点是非常简单方便,无侵入性,基本覆盖常用的接口数据类型。
支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
安装: npm install mockjs
前端的postman,是不是可以这么理解
基本使用
- 在项目中创建mock目录,新建index.js文件
1 | //引入mockjs |
- 组件中调用mock.js中模拟的数据接口,这时返回的response就是mockjs中用Mock.mock(‘ur’,data)中设置的data
1 | import axios from 'axios' |
核心方法
Mock.mock( rurl?, rtype?, template|function( options ))
- rurl,表示需要拦截的 URL,可以是 URL 字符串或 URL 正则
- rtype,表示需要拦截的 Ajax 请求类型。例如 GET、POST、PUT、DELETE 等。
- template,表示数据模板,可以是对象或字符串
- function,表示用于生成响应数据的函数。设置延时请求到数据
1 | //延时400ms请求到数据 |
贴两个官方文档在这里,方便后续查看:Getting Started · nuysoft/Mock Wiki 示例 | Mock.js中文网
也可以顺带了解一下mockjs的数据生成规则,以后可能会用到。
P15 vue-element-admin后台集成方案
vue-element-admin介绍
- vue-element-admin 是一个后台前端解决方案,它基于 vue 和 element-ui实现。
- 内置了 i18 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型提供了丰富的功能组件。
- 可以快速搭建企业级中后台产品原型。
- 地址:https://panjiachen.github.io/vue-element-admin-site/zh/guide/
- 效果演示文档:http://panjiachen.github.io/vue-element-admin
P16 JWT跨域认证
Session认证
互联网服务离不开用户认证。一般流程是下面这样。
- 用户向服务器发送用户名和密码。
- 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色登录时间等。
- 服务器向用户返回一个 session id,写入用户的 Cookie。
- 用户随后的每一次请求,都会通过 Cookie,将 session id 传回服务器。
- 服务器收到 session id,找到前期保存的数据,由此得知用户的身份。
Session认证流程
session 认证的方式应用非常普遍,但也存在一些问题,扩展性不好,如果是服务器集群,或者是跨域的服务导向架构,就要求 session 数据共享,每台服务器都能够读取 session,针对此种问题一般有两种方案:
- 一种解决方案是session 数据持久化,写入数据库或别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大。
- 一种方案是服务器不再保存 session 数据,所有数据都保存在客户端,每次请求都发回服务器。Token认证就是这种方案的一个代表。
Token认证
Token 是在服务端产生的一串字符串,是客户端访问资源接口(API)时所需要的资源凭证,流程如下:
- 客户端使用用户名跟密码请求登录,服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
- 客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者localStorage里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 token
- 服务端收到请求,然后去验证客户端请求里面带着的 token,如果验证成功就向客户端返回请求的数据
Token认证的特点
- 基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放token 数据。
- 用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力减少频繁的查询数据库
- token 完全由应用管理,所以它可以避开同源策略
JWT
- JSON Web Token(简称 JWY)是一个token的具体实现方式,是目前最流行的跨域认证解决方案。
- JWT 的原理是,服务器认证以后,生成一个JSON 对象,发回给用户,具体如下:
1 | { |
- 用户与服务端通信的时候,都要发回这个JSON 对象。服务器完全只靠这个对象认定用户身份。
- 为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。
JWT 的由三个部分组成,依次如下:
- Header(头部)
- Payload(负载)
- Signature(签名)
三部分最终组合为完整的字符串,中间使用分隔,如下:
- Header.Payload.Signature
eyJhbGci0iJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIi0iIxMjMBNTY30DkwIiwibmFtzSI6IkpvaG4gRG9lIiwiaxNTb2NpYWwionRydwy9.
4pcPyMD89olPSyXnrXCiTwXyr4BsezdI1AVTmud2fU4
Payload
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JT规定了7个官方字段,供选用。
- iss (issuer): 签发人
- exp(expiration time): 过期时间
- sub(subject): 主题
- aud(audience): 受众
- nbf(Not Before): 生效时间
- iat(lssued At): 签发时间
- jti (JWT ID): 编号
注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在个部分。
这个 JSON 对象也要使用 Base64URL 算法转成字符串。
Signature
- Signature 部分是对前两部分的签名,防止数据篡改。
- 首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户
- 然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名
1 | HMAGSHA256( |
JWT的特点
- 客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在localStorage.
- 客户端每次与服务器通信,都要带上这个JT,可以把它放在 Cookie 里面自动发送,但是这样不能跨域。
12:45 - 更好的做法是放在 HTTP 请求的头信息
Authorization
字段里面,单独发送。
JWT的实现
加入依赖
1
2
3
4
5<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
生成Token
1 | //7天过期 |
解析Token
1 | //解析token |
P18 阿里云服务器使用
云服务器概念
- 云服务器(Elastic Compute Service,ECS)是一种简单高效、安全可靠、处理能力可弹性伸缩的计算服务。
- 其管理方式比物理服务器更简单高效。用户无需提前购买硬件,即可迅速创建或释放任意多台云服务器。
- ECS的最重要的特点是弹性,支持垂直和水平扩展两种能力。
云服务器的特点
- ECS一般提供自动宕机迁移、数据备份和回滚、系统性能报警等功能,稳定性更高
阿里云ECS的使用
后面剩下的基本就是一些云环境的配置了。。。有机会后面单开一篇记载。