第一次体验一下前后端分离项目
第一次完整的体验一下前后端分离项目
技术栈
- 前台:Vue3,vue router,vuex,element-plus,axios
- 后台:SpringBoot,Mybatis-plus
写项目之前,只是耳闻前后端分离
后端-负责业务逻辑,写个接口,用json传数据。
前端-接收后端传送的数据并对其渲染。
也就到这个程度,但具体用什么技术实现的,以及落地的代码实现还没有敲过,就结合这次机会。一起学习学习
现有的能力
因为是第一次用springboot-vue 所以很多东西都是边敲先学的,就简单记录一下,所涉及的陌生的知识点。
- 前台:html+css+javascript jquery
- 后台:SpringBoot,Mybatis
发现Mybatis-plus还挺好用,就顺便结合看一看Mybatis了解一下其实现原理吧。详情见——链接
首先是关于前端的一些琐碎的知识点
以下我的举例并不准确,只是为了java人员快速理解上手。
ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准。
ES6之于js,相当于,jdk11之于java。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
Node.js之于js,相当于,jvm之于java. (2022年1月14日删)欢迎大家一起讨论
上面这一点不太合适
应该是 V8之于js,相当于,jvm之于java.
(node.js只是js的一个运行环境)
NPM (Node Package Manager)来自各大洲的开源软件开发者使用 npm 互相分享和借鉴。包的结构使您能够轻松跟踪依赖项和版本。
NPM之于js,相当于,Maven之于java.
Vue.js 是用于构建交互式的 Web 界面的库。
一个比较流行的前端框架
跨域
因为是前后端分离的项目,需要把两个工程分为不同的端口。
在vue.config.js中 有关跨域的设置
// 跨域配置
module.exports = {
devServer: { //记住,别写错了devServer//设置本地默认端口 选填
port: 9876,
proxy: { //设置代理,必须填
'/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
target: 'http://localhost:9090', //代理的目标地址
changeOrigin: true, //是否设置同源,输入是的
pathRewrite: { //路径重写
'/api': '' //选择忽略拦截器里面的单词
}
}
}
}
}
异步交互
这次项目的异步交互用到了axios ——一种对原生XMLHttpRequest的封装。它是一个用于浏览器和 nodejs 的 HTTP 客户端,符合最新的ES规范。
说到 对原生XMLHttpRequest的封装
不得不说一说 原生的ajax 和jquery的ajax
JavaScript的Ajax
Ajax的全称是Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求,而不需要重载(刷新)整个页面。
Ajax使用XMLHttpRequest对象取得新数据,然后再通过 DOM 将新数据插入到页面中。另外,虽然名字中包含 XML 的成分,但 Ajax 通信与数据格式无关; 这种技术就是无须刷新页面即可从服务器取得数据,但不一定是 XML 数据。使用方法如下:
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
启动请求:
xhr.open(method, url, boolean);
xhr.send();
注:
1,xhr.open参数含义:
method:请求方式,post、get等
url: 请求链接,只能向同源的url发送请求
boolean:是否异步请求,true:异步, false: 同步,默认为true
2,调用 open()方法并不会真正发送请求, 而只是启动一个请求以备发送。
3,send()方法接收一个参数,即要作为请求主体发送的数据(post方法会使用,get方法直接传null)。如果不需要通过请求主体发送数据,则必须传入 null,因为这个参数对有些浏览器来说是必需的。调用send()之后,请求就会被分派到服务器。
XMLHttpRequest对象的异步请求示例如下:
function success(text) {
console.log(text);
}
function fail(code) {
console.log(code);
}
var xhr = new XMLHttpRequest(); // 新建XMLHttpRequest对象
xhr.onreadystatechange = function () {
// 状态发生变化时,函数被回调
if (xhr.readyState === 4) { // 成功完成
// 判断响应结果:
if (xhr.status === 200) {
// 成功,通过responseText拿到响应的文本:
return success(xhr.responseText);
} else {
// 失败,根据响应码判断失败原因:
return fail(xhr.status);
}
} else {
// HTTP请求还在继续...
}
}
// 发送请求:
xhr.open('get', '/api/categories');
xhr.send(null);
xhr的属性含义如下:
responseText: 作为响应主体被返回的文本。
responseXML: 如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存响应数据的 XML DOM 文档。
status: 响应的 HTTP 状态。
statusText: HTTP 状态的说明。
readyState :表示请求/响应过程的当前活动阶段。可取值如下。
0: 未初始化。尚未调用 open()方法。
1: 启动。已经调用 open()方法,但尚未调用 send()方法。
2: 发送。已经调用 send()方法,但尚未接收到响应。
3: 接收。已经接收到部分响应数据。
4: 完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
只要 readyState 属性的值由一个值变成另一个值,都会触发一次 readystatechange 事件。可以利用这个事件来检测每次状态变化后readyState 的值。通常,我们只对 readyState 值为 4 的阶段感兴趣,因为这时所有数据都已经就绪。不过,必须在调用 open()之前指定 onreadystatechange事件处理程序才能确保跨浏览器兼容性。
另外,在接收到响应之前还可以调用 abort()方法来取消异步请求:
xhr.abort();
调用这个方法后,XHR 对象会停止触发事件,而且也不再允许访问任何与响应有关的对象属性。在终止请求之后,还应该对 XHR 对象进行解引用操作。由于内存原因,不建议重用 XHR 对象。
jQuery的Ajax
$.ajax({
url:"",
type:"GET",
contentType: '',
async:true,
data:{},
dataType:"",
success: function(){
}
});
url 必填项,规定把请求发送到哪个 URL。
type 以什么样的方式获取数据,是get或post
contentType:发送POST请求的格式,默认值为’application/x-www-form-urlencoded;
charset=UTF-8’,也可以指定为text/plain、application/json
async 是否异步执行AJAX请求,默认为true,千万不要指定为false
data 发送的数据,可以是字符串、数组或object。如果是GET请求,data将被转换成query附加到URL上,如果是POST请求,根据contentType把data序列化成合适的格式;
dataType
接收的数据格式,可以指定为’html’、‘xml’、‘json’、'text’等,缺省情况下根据响应的Content-Type猜测。
success 可选。执行成功时返回的数据。
缺点:
本身是针对mvc的编程模式,不太适合目前mvvm的编程模式。jQuery本身比较大,如果单纯的使用ajax可以自己封装一个,不然会影响性能体验。
axios具有以下特征:
- 从浏览器中创建 XMLHttpRequest
- 支持 Promise API
- 客户端支持防止CSRF
- 提供了一些并发请求的接口
- 从 node.js 创建 http 请求
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
设置全局的 axios 默认值
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
注:axios 的 headers的 content-type 默认是 “application/json ”
默认情况下,axios将JavaScript对象序列化为JSON,如果是get请求,对请求参数不用做任何处理,但是如果是post请求,并且Content-Type 为application/x-www-form-urlencoded,需要使用URLSearchParams API格式化请求参数, 否则Content-Type依然是application/json
var params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
get请求,以下3中写法完全等价
// 第一种写法
axios.get('/user?id=12345&name=xiaoming')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 第二种写法
axios.get('/user', {
params: {
id: '12345',
name: 'xiaoming'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 第三种写法
axios({
url: '/user',
method: 'get',
params: {
id: '12345',
name: 'xiaoming'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
post请求,以下2种写法完全等价
// 第一种写法
axios({
url: '/user',
method: 'post',
headers: {
'Content-Type': 'application/json'
},
data: {
id: '12345',
name: 'xiaoming'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 第二种写法
var url = '/user';
var data = {
id: '12345',
name: 'xiaoming'
};
axios.post(url, data, {
headers: {
'Content-Type': 'application/json'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
执行多个并发请求
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));
创建实例
可以使用自定义配置新建一个 axios 实例
axios.create([config])
var instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
配置会以一个优先顺序进行合并,顺序由低到高为
1,在 node_modules/axios/lib/defaults.js 找到的库的默认值
2,实例的 defaults 属性
3,请求的 config 参数
// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();
// 覆写库的超时默认值
// 现在,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;
// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
timeout: 5000
});
拦截器
在请求发出之前或响应被 then 或 catch 处理前拦截它们做预处理。
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
}, function (error) {
// 对请求错误做些什么
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
}, function (error) {
// 对响应错误做点什么
});
可以在稍后移除拦截器:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
可以为自定义 axios 实例添加拦截器
var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

浙公网安备 33010602011771号