【JavaScript】从AJAX到Fetch、axios


前言:

在前后端交互的过程中,有很多数据请求的方式,例如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)
 })

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CUG-GZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值