轻松入门vue系列

六、Vue前后端交互

项目中一般结合async/await语法使用axios调用接口

1. 前后端交互模式

1. 接口调用方式

原生ajax、基于jQuery的ajax、fetch、axios

2. 传统的URL

格式:schema://host:port/path?query#fragment

  1. schema:协议,例如http、https、ftp等。
  2. host:域名或者IP地址。
  3. port:端口,http默认端口80,可以省略。
  4. path:路径,例如/abc/a/b/c
  5. query:查询参数,例如uname=lisi&age=12
  6. fragment:锚点(哈希Hash),用于定位页面的某个位置

3. Restful形式的URL

HTTP请求方式

  1. GET 查询
  2. POST 添加
  3. PUT 修改
  4. DELETE 删除

2. Promise的相关概念和用法

JS中常见的异步调用:定时任务、ajax、事件函数

Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。

使用Promise主要有以下好处:

  • 可以避免多层异步调用嵌套问题(回调地狱)
  • Promise对象提供了简介的API,使得控制异步操作更加容易
Promise基本用法
  • 实例化Promise对象,构造函数中传递函数,该函数中用于处理异步任务。

  • resolve和reject两个(方法)参数用于处理成功和失败两种情况,并通过p.then获取处理结果。

var p = new Promise(function(resolve,reject){
//成功时调用resolve()
//失败时调用reject()
});
p.then(function(ret){
//从resolve得到正常结果
},function(ret){
//从reject得到错误信息
});
then参数中的函数返回值
  1. 返回Promise实例对象

返回该实例对象用于调用下一个then

p.then(function(ret){
return new Promise(...)
}).then(...)
  1. 返回普通值

返回的普通值会直接传递给下一个then,通过then函数中函数的参数接收该值(底层会对返回的普通值封装为一个Promise使得能够继续调用then)

p.then(function(ret){
return '莫逸风';
}).then(function(ret){
alert(ret); //莫逸风
})
基于Promise处理多个Ajax请求demo
<script>
//Promise基本使用,原生ajax
function getText(url) {
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
//readyState表示文档状态
if (xhr.readyState != 4) return;
if (xhr.readyState == 4 && xhr.status == 200){
//处理正常情况
resolve(xhr.responseText);
}else {
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
}
//链式调用解决回调地狱,return一个新的调用就可以继续调用新的then()了。
getText('http://localhost:8088/saymo').then(
function (data) {
alert(data);
return getText('http://localhost:8088/sayyi');
},function (info) {
alert(info);
}
).then(
function (data) {
alert(data);
return getText('http://localhost:8088/sayfeng')
}
).then(
function (data) {
alert(data);
}
);
</script>

上方调用方式会调用后端,产生跨域问题(解决方案回头仔细研究,先放一段代码(SpringBoot))

跨域解决方案参考

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; @Configuration
public class CorsConfig {
public CorsConfig(){
} @Bean
public CorsFilter corsFilter(){
//1.添加cors配置信息
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:63343");
//设置是否发送cookie信息
config.setAllowCredentials(true);
//设置允许请求的方式
config.addAllowedMethod("*");
//设置允许的header
config.addAllowedHeader("*"); //2.为url添加映射路径
UrlBasedCorsConfigurationSource corsSource = new UrlBasedCorsConfigurationSource();
corsSource.registerCorsConfiguration("/**",config); //3.返回从新定义好的corsSource
return new CorsFilter(corsSource);
}
}
Promise常用API
  1. 实例方法

p.then() //得到异步任务的处理结果
p.catch() //获取异常信息
p.finally() //成功与否都会执行(尚且不是正式标准)

demo

<script>
function foo() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
//resolve(123)//正常情况
reject("出错了");//错误情况
},1000)
})
}
foo().then(function (data) {
alert(data);
}).catch(function (data) {
alert(data);
}).finally(function () {
alert("结束了")
})
//与上面效果相同
foo().then(function (data) {
alert(data);
},function (data) {
alert(data);
}).finally(function () {
alert("结束了")
})
</script>
  1. 对象方法

Promise.all()并发处理多个异步任务,所有任务都执行完成才能得到结果

Promise.race()并发处理多个异步任务,只要有一个任务完成就能得到结果

demo

<script>
function getText(url) {
var p = new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
//readyState表示文档状态
if (xhr.readyState != 4) return;
if (xhr.readyState == 4 && xhr.status == 200){
//处理正常情况
resolve(xhr.responseText);
}else {
reject('服务器错误');
}
};
xhr.open('get',url);
xhr.send(null);
});
return p;
} var p1 = getText("http://localhost:8088/saymo");
var p2 = getText("http://localhost:8088/sayyi");
var p3 = getText("http://localhost:8088/sayfeng"); //result是一个数组形式的三个数据,顺序和p1,p2,p3顺序相同
Promise.all([p1,p2,p3]).then(function (result) {
alert(result);
})
//result返回一个数据,最快返回的一个
Promise.race([p1,p2,p3]).then(function (result) {
alert(result);
})
</script>

3. fetch进行接口调用

更加简单的数据获取方式,功能更强大、更灵活,可以看做是xhr的升级版

基于Promise实现

fetch基本用法

语法结构

fetch(url).then(fn2)
.then(fn3)
...
.cach(fn)

基本用法

fetch('/abc').then(data=>{
return data.text();
}).then(ret=>{
//这里得到的才是最终的数据
console.log(ret);
})

demo

<script type="application/javascript">
/**
* Fetch API 基本用法
*/
fetch('http://localhost:8088/saymo').then(function (data) {
//text()方法属于fetchAPI的一部分,它返回一份Promise实例对象,用于获取后台返回的数据
return data.text();
}).then(function (data) {
alert(data);
})
</script>
fetch请求参数
  1. 常用配置选项

method(String):HTTP请求方法,默认为GET(GET、POST、PUT、DELETE)

body(String):HTTP的请求参数

headers(Object):HTTP的请求头,默认为{}

  1. get请求方式的参数传递

常规

<script>
fetch('http://localhost:8088/sayHi?name="莫逸风',{
method:'get'
}).then(function (data) {
return data.text();
}).then(function (data) {
alert(data);
});
</script>

restful形式


  1. post请求方式的参数传递

参数form表单形式

fetch('http://localhost:8088/login',{
method:'post',
body:,
headers:{
'Content-Type':'application/x-www-form-urlencoded',
}
}).then(function (data) {
return data.text();
}).then(function (data) {
alert(data);
})

参数json表单形式

fetch('http://localhost:8088/login',{
method:'post',
body:JSON.stringify({
name:'莫逸风',
pass:'1234',
}),
headers:{
'Content-Type':'application/json',
}
}).then(function (data) {
return data.text();
}).then(function (data) {
alert(data);
});
fetch响应结果

text():将返回体处理成字符串类型

json():返回结果和JSON.parse(responseText)一样

fetch('http://localhost:8088/sayhi?name=莫逸风',{
method:'get'
}).then(function (data) {
return data.json();
}).then(function (data) {
alert(data);
});

4. axios进行接口调用

axios(官网:https://github.com/axios/axios)是一个基于Promise用于浏览器和node.js的HTTP客户端

中文说明文档

它具有一下特征:

  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和相应
  • 自动转换JSON数据
axios基本用法
//去github下载文件,此js位于axios-master\dist
<script src="axios.js"></script>
<script>
axios.get('http://localhost:8088/saymo').then(function (ret) {
//data属性是固定的用法,用于获取后台的实际数据
alert(ret.data)
})
</script>
axios的常用API(参数传递)
  • get:查询数据
  • post:添加数据
  • put:修改数据
  • delete:删除数据
  1. get传递参数

通过URL传递参数

axios.get('http://localhost:8088/sayhi?name=莫逸风').then(function (ret) {
alert(ret.data)
})

restful风格接口


通过params选项传递参数

axios.get('http://localhost:8088/sayhi',{
params:{
name:"莫逸风"
}
}).then(function (ret) {
//data属性是固定的用法,用于获取后台的实际数据
alert(ret.data)
})
  1. POST传递参数

通过对象传递参数(默认传递的是json格式的数据)

axios.post('http://localhost:8088/login',{
name:"莫逸风",
pass:"1234",
}).then(function (ret) {
//data属性是固定的用法,用于获取后台的实际数据
alert(ret.data)
})

通过URLSearchParams传递参数(application/x-www-form-urlencoded)

var param = new URLSearchParams();
param.append('name','莫逸风');
param.append('pass','12345');
axios.post('http://localhost:8088/login',param).then(function (ret) {
//data属性是固定的用法,用于获取后台的实际数据
alert(ret.data)
})
  1. axios的响应结果
  • data:实际响应回来的数据
  • headers:响应头信息
  • status:响应状态码
  • statusText:响应状态信息
axios.post('http://localhost:8088/login',param).then(function(ret){
console.log(ret);//所有数据都包含在此对象中
//对于json形式的响应数据可以直接获取,不需要转换
alert(ret.data.name);
})
  1. axios的全局配置
axios.defaults.timeout = 3000;  //超时时间
//默认地址,再写请求的时候只需要写后面的路由就行了
axios.defaults.baseURL = 'http://localhost:3000/app';
axios.defaults.headers['mytoken']='aqwerwqwerqwer2ewrwe23eresdff23'//设置请求头

demo

//配置请求的基准URL地址
axios.defaults.baseURL = 'http://localhost:8088/';
axios.get('sayhi?name=莫逸风').then(function (ret) {
//data属性是固定的用法,用于获取后台的实际数据
alert(ret.data)
})
//注意,添加请求头跨域需要后端设置AllowedHeader
//修改请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
  1. axios拦截器

请求拦截器

在请求发出之前设置一些信息

axios.interceptors.request.use(function (config) {
config.baseURL = "http://localhost:8088/";
alert(config.url);
return config;
},function (err) {
console.log(err);
}) axios.get('sayhi?name=莫逸风').then(function (ret) {
//data属性是固定的用法,用于获取后台的实际数据
alert(ret.data)
})

响应拦截器(拦截器放到请求之上)

在获取数据之前对数据做一些加工处理

axios.interceptors.response.use(function (res) {
var data = res.data;
return data;
},function (err) {
console.log(err);
}) axios.get('sayhi?name=莫逸风').then(function (res) {
//data属性是固定的用法,用于获取后台的实际数据
alert(res)
})

5. asyns/await接口调用

async/await的基本用法
  • async/await是ES7引入的语法,可以更加方便的进行异步操作

  • async关键字用于函数上(async函数的返回值是Promise实例对象)

  • await关键字用于async函数中(await可以得到异步的结果)

await后跟一个Promise对象实现异步任务,async返回值是一个Promise对象

<script src="axios.js"></script>
<script>
axios.defaults.baseURL = 'http://localhost:8088/';
async function queryData(){
var ret = await axios.get('saymo');
//alert(ret.data);
return ret.data;
}
queryData().then(function (data) {
alert(data);
});
</script>
多个异步请求的场景

不需要.then来保证顺序。

<script>
axios.defaults.baseURL = 'http://localhost:8088/';
async function queryData(){
var ret = await axios.get('saymo');
alert(ret.data);
var ret1 = await axios.get('sayyi');
alert(ret1.data);
var ret2 = await axios.get('sayfeng');
return ret2.data;
}
queryData().then(function (data) {
alert(data);
});
</script>

三、vue前后端交互(轻松入门vue)的更多相关文章

  1. 一、vue基础语法(轻松入门vue)

    轻松入门vue系列 Vue基础语法 一.HelloWord 二.MVVM设计思想 三.指令 1. v-cloak 2. v-text 3. v-html 4. v-show 4. v-pre 5. v ...

  2. 四、vue前端路由(轻松入门vue)

    轻松入门vue系列 Vue前端路由 七.Vue前端路由 1. 路由的基本概念与原理 后端路由 前端路由 实现简单的前端路由 vue-router基本概念 2. vue-router的基本使用 基本使用 ...

  3. 轻松入门vue系列

    一.vue基础语法 二.vue组件化开发 三.Vue前后端交互 四.vue前端路由 喜欢不要忘了点个赞哟

  4. vue前后端分离

    axios前后端交互 安装 一定要安装到`项目目录下 cnpm install axios 配置 在main.js中配置 //配置axios import axios from 'axios' Vue ...

  5. Vue - 与后端交互

    零:与后端交互 - ajax 版本1 - 出现了跨域问题 前端:index.html <!DOCTYPE html> <html lang="en"> &l ...

  6. Vue之前后端交互

    Vue之前后端交互 一.前后端交互模式 接口调用方式 原生ajax 基于jQuery的ajax fetch axios 异步 JavaScript的执行环境是「单线程」 所谓单线程,是指JS引擎中负责 ...

  7. Flask + vue 前后端分离的 二手书App

    一个Flask + vue 前后端分离的 二手书App 效果展示: https://blog.csdn.net/qq_42239520/article/details/88534955 所用技术清单 ...

  8. 喜大普奔,两个开源的 Spring Boot + Vue 前后端分离项目可以在线体验了

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

  9. 两个开源的 Spring Boot + Vue 前后端分离项目

    折腾了一周的域名备案昨天终于搞定了. 松哥第一时间想到赶紧把微人事和 V 部落部署上去,我知道很多小伙伴已经等不及了. 1. 也曾经上过线 其实这两个项目当时刚做好的时候,我就把它们部署到服务器上了, ...

随机推荐

  1. python + mysql 实现表删除数据

    实例如下: import pymysqldef Delete_From(): #打开数据库链接 db = pymysql.connect("localhost","roo ...

  2. 在java中为啥要重写toString 方法?

    在java中为啥要重写toString 方法?下面以一个简单的例子来说明. 先定义一个test5类.并写它的get,set方法. package test5; public class Test5 { ...

  3. java 向Redis中存放数据 List<Device>转String

    /** * redis服务 */ @Autowired private RedisService redisService; //创建 Device  对象 Device no = new Devic ...

  4. javascript中“==”,“===”和“Object.is(a,b)”的区别

    作为两个量比较的三种方式"==","==="和"Object.is(a,b)"有一定区别,如下(具体见MDN): (1)Object.is( ...

  5. springmvc学习指南 之---第24篇 国际化问题

    writedby 张艳涛,今天一天就搞了一个这个问题,主要是下路,遇到springmvc-config.web的配置和拦截器的使用问题, 看了几天的spring发现都没讲拦截器,之前看了两天sprin ...

  6. CF201C Fragile Bridges TJ

    本题解依旧发布于洛谷,如果您能点个赞的话--(逃 前言 题目链接 正解:动态规划 思路不是很好想,想出来了应该就没有多大问题了,但是需要处理的细节较多,再加上水水的样例,难度应该是偏难的.个人感觉应该 ...

  7. (数据科学学习手札126)Python中JSON结构数据的高效增删改操作

    本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在上一期文章中我们一起学习了在Python ...

  8. Java中泛型的详细解析,深入分析泛型的使用方式

    泛型的基本概念 泛型: 参数化类型 参数: 定义方法时有形参 调用方法时传递实参 参数化类型: 将类型由原来的具体的类型参数化,类似方法中的变量参数 类型定义成参数形式, 可以称为类型形参 在使用或者 ...

  9. Python之replace()方法失效

    1.背景 Titanic存活率预测案例: # 读取数据 df_train = pd.read_csv("./data/train.csv") df_train.head() OUT ...

  10. [06 Go语言基础-包]

    [06 Go语言基础-包] 包 什么是包,为什么使用包? 到目前为止,我们看到的 Go 程序都只有一个文件,文件里包含一个 main 函数和几个其他的函数.在实际中,这种把所有源代码编写在一个文件的方 ...