目录


前言:

在前后端交互的过程中,有很多数据请求的方式,例如AJAX、Fetch、axios等等,下面就一一来简单列举一下。

我们先来看一下URL的两种的形式:

  1. 传统的URL格式如下:
scheme://host:port/path?query#fragment

其中:

scheme: 表示协议,如Http, Https, Ftp等;
host: 表示所访问资源所在的主机名:如:www.baidu.com;
port: 表示端口号,默认为80;
path: 表示所访问的资源在目标主机上的储存路径;
query: 表示查询条件;
fragment:表示锚点(哈希),用于定位页面的某个位置。

例如: http://www.baidu.com/search?words=Baidu
  1. restful形式的URL

(1)HTTP的请求方式:

  • GET 查询
  • POST 添加
  • PUT 修改
  • DELETE 删除

(2)符合规则的URL:(提交方式不同)

http://www.hello.com/books  GET
http://www.hello.com/books POST
http://www.hello.com/books/123 PUT(对id为123的数据进行修改)
http://www.hello.com/books/123 DELETE(对id为123的数据进行删除)

1. AJAX

1.1 简介

AJAX 是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。

1.2 特点

  1. 优点
  • 不需要插件支持(一般浏览器且默认开启 JavaScript 即可)
  • 用户体验极佳(不刷新页面即可获取可更新的数据)
  • 提升 Web 程序的性能(在传递数据方面做到按需发送,不必整体提交)
  • 减轻服务器和带宽的负担(将服务器的一些操作转移到客户端)
  1. 缺点
  • 前进、后退的功能被破坏(因为 AJAX 永远在当前页,不会记录前后页面)
  • 搜索引擎的支持度不够(因为搜索引擎爬虫还不能理解 JS 引起变化数据的内容)

1.3 常见状态码

100 ~ 199 表示连接继续
200 ~ 299 表示各种意义上的成功
300 ~ 399 表示重定向
400 ~ 499 表示各种客户端错误
500 ~ 599

1.4 使用方法

AJAX 包括以下几个步骤:

  1. 创建XMLHttpRequest对象,也就是创建一个异步调用对象
  2. 创建一个新的HTTP请求,并指定其请求的方法、URL及验证信息
  3. 设置响应 HTTP 请求状态变化的函数
  4. 发送 HTTP 请求
  5. 获取异步调用返回的数据
  6. 使用 JavaScript 和 DOM 实现局部刷新
//原生AJAx
var request = new XMLHttpRequest(); // 新建XMLHttpRequest对象;
request.onreadystatechange = function () { // 状态发生变化时,函数被回调;
if (request.readyState === 4) { // 成功完成
// 判断响应结果:
if (request.status === 200) {
// 成功,通过responseText拿到响应的文本:
} else {
// 失败,根据响应码判断失败原因:
}
} else {
// HTTP请求还在继续...
}
}
// 发送请求:
request.open("POST","/skill-ajax/a/login",true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send();
alert('请求已发送,请等待响应...');

// readyState值说明
// 0,初始化,XHR对象已经创建,还未执行open
// 1,载入,已经调用open方法,但是还没发送请求
// 2,载入完成,请求已经发送完成
// 3,交互,可以接收到部分数据

// status值说明
// 200:成功
// 404:没有发现文件、查询或URl
// 500:服务器产生内部错误

使用jQuery进行AJAX请求:

//jQuery中的AJAX
$.ajax({
method: 'GET', // 1.9.0本版前用'type'
url: url,
data: data,
dataType: dataType,
success: function() {
console.log('执行成功');
},
error: function() {
console.log('执行出错');
}
})

使用jQuery进行AJAX请求时它具有以下特点:
(1)优点:

  • 对原生XHR的封装,做了兼容处理,简化了使用
  • 增加了对JSONP的支持,可以简单处理部分跨域

(2)缺点:

  • 如果有多个请求,并且有依赖关系的话,容易形成回调地狱
  • 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
  • ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery,很不合理

1.5 使用Promise封装AJAX

这里不多做介绍,之前写了一篇相关文章:​​利用Promise封装Ajax中get和post方法​

2. Fetch

2.1 Fetch简介

Fetch是基于Promise实现的,支持 async/await,它有更加简单的数据获取方式,功能更加强大、更灵活,可以看做是xhr的升级版。

// 原生XHR
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText) // 从服务器获取数据
}
}
xhr.send()

// fetch
fetch(url)
.then(response => {
return response.json();
})
.then(data => console.log(data)) // 这里得到的才是真正的数据
.catch(error => console.log(error))

2.2 常用参数

常用的参数配置:
(1)​​​method​​​(String): HTTP请求方法,默认为GET (GET、POST、PUT、DELETE)
(2)​​​body​​​(String): HTTP的请求参数
(3)​​​headers​​(Object): HTTP的请求头,默认为{}

2.3 基本用法

  1. GET 请求方式
//使用普通URL进行传递参数
fetch('/abc?id=123')
.then(response => {
return response.json();
})
.then(data => console.log(data))
.catch(error => console.log(error))

// 使用restful形式进行传参
fetch('/abc/123',{
method:'get'
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))
  1. DELETE请求方式

delete请求方式和get方式类似:

//使用普通URL进行传递参数
fetch('/abc?id=123',{
method:'delete'
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))

// 使用restful形式进行传参
fetch('/abc/123',{
method:'delete'
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))
  1. POST请求方式
//以普通参数形式请求
fetch('/abc',{
method:'post'
body:'uname=zhangsan&psw=123',
headers:{
'Content-Type' : 'application/X-www-form-urlencoded'
}
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))

// 以json格式进行请求
fetch('/abc',{
method:'post'
body:JSON.stringify({
uname:'zhangsan',
psw:'123'
})
headers:{
'Content-Type' : 'application/json'
}
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))
  1. PUT请求方式

put请求方式和post类似:

//以普通参数形式请求
fetch('/abc/123',{ //123要修改数据的id
method:'put'
body:'uname=zhangsan&psw=123',
headers:{
'Content-Type' : 'application/X-www-form-urlencoded'
}
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))

// 以json格式进行请求
fetch('/abc/123',{
method:'put'
body:JSON.stringify({
uname:'zhangsan',
psw:'123'
})
headers:{
'Content-Type' : 'application/json'
}
}).then(response => {
return response.json();
}).then(data => console.log(data))
.catch(error => console.log(error))

2.4 响应结果

Fetch响应数据的格式主要有以下两种:

  • ​text()​​:将返回体处理成字符串类型
  • ​json()​​​:返回结果和​​JSON.parse​​(responseText)一样

我们上面使用的是​​json()​​​格式,如果想用​​text()​​格式,直接替换即可。

2.5 特点

(1)优点:

在配置中,添加​​mode:'no-cors'​​就可以跨域了

fetch('/users.json', {
method: 'post',
mode: 'no-cors',
data: {}
}).then(function() { /* handle response */ });

(2)缺点:

  • fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
  • fetch默认不会带cookie,需要添加配置项。
  • fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费。
  • fetch没有办法原生监测请求的进度,而XHR可以。

3. axios

3.1 axios简介

axios是一个基于​​promise​​​的HTTP库,可以用在浏览器和 ​​node.js​​​ 中。它本质也是对原生​​XMLHttpRequest​​​的封装,只不过它是​​Promise​​的实现版本,符合最新的ES规范。

Vue作者尤雨溪推荐使用axios进行数据请求。

axios具有以下特点:

  • 支持浏览器和 node.js
  • 支持 promise
  • 能拦截请求和响应
  • 自动转换JSON数据
  • 提供了并发请求的接口

3.2 基本用法

  1. GET请求和DELETE请求

get请求和delete请求的用法类似,下面只写get请求:

//通过传统的URL地址传递参数
axios.get('/user?id=12345')
.then(function (response) {
console.log(response); // 这是返回的一个封装好的对象
console.log(response.data); // 这才是后台响应的真正的数据
})
.catch(function (error) {
console.log(error);
});

//通过restful形式的URL进行传参
axios.get('/user/id=12345')
.then(function (response) {
console.log(response);
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});

//通过params对象传递参数
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
  1. POST请求和PUT请求

post和put类似,这里只列举post请求方式:

// 通过默认选项传参(默认传递的是json形式的数据)
axios.post('/user', {
uname:'zhangsan',
psw:'123'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});

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

const params = new URLSeardhParams();
params . append('uname', 'zhangsan');
params . append ('psw', '123');

axios.post('/user', params)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
  1. 并发请求
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){
//当这两个请求都完成的时候会触发这个函数,两个参数分别代表返回的结果
}))

3.3 响应结果

我们上文中只说了响应的数据​​response.data​​,响应结果中还有以下主要属性:

  • ​data​​: 实际响应回来的数据
  • ​headers​​ : 响应头信息
  • ​status​​ : 响应状态码
  • ​statusText​​ : 响应状态信息

3.4 全局配置

在发送请求之前,我们可以对axios请求设置全局配置:

// 超时时间
axios.defaults.timeout = 3000;
//设置默认地址,配置请求的基准URL地址,在请求时就可以不写这一部分
axios.defaults.baseURL =http://www.baidu.com';
// 设置请求头
axios.defaults.headers[ 'mytoken'] = 'helloworld'

3.5 拦截器

  1. 请求拦截器

请求拦截器的作用是在发出请求之前设置一些信息:

axios.interceptors.request.use(function(config){
//在请求发出之前进行信息设置
config.headers.mytoken = 'helloworld' // 和全局配置设置请求头效果一样,但是更加灵活
return config;
},function(error){
// 处理响应的错误信息
console.log(error);
});
  1. 响应拦截器

响应拦截器的作用是在获取数据之前对数据进行一些加工处理:

axios.interceptors.response.use(function(response){
//对返回的数据进行处理
var data = response.data;
return data;
},function(error){
//处理响应的错误信息
console.log(error);
});

4. async / await

​async / await​​方法是ES7中引入的新语法,可以更加便捷的进行异步操作。其中:

  • ​async​​​关键字用于函数上(​​async​​函数的返回值是Promise实例对象)
  • ​await​​​关键字用于async函数当中(​​await​​可以得到异步的结果)
async function queryData (id) {
const ret = await axios.get('/data'); //可以直接得到调用结果,不需要再使用then
return ret;
}
// 因为上一步返回的Promise对象,所以通过调用then,可以直接获得上面获取到的数据
queryData.then (ret=> {
console.log (ret)
})

使用​​async / await​​ 处理多个异步请求:

对于多个异步请求 ,我们只要在async函数中按照顺序处理异步任务即可:

async function queryData(id) {
const info = await axios. get('/async1') ;
const ret = await axios . get ( 'async2?info='+info.data) ;
return ret;
}
queryData.then (ret=>{
console.log (ret)
})

这大概就是这些请求方式的简单介绍以及基本使用方法。【完】