2025年3月15日 星期六 甲辰(龙)年 月十四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

前端网络请求:从 XMLHttpRequest 到 Axios

时间:02-13来源:作者:点击数:21
前言

在网络应用中,前后端的数据交互是必不可少的一部分。本文将带你从最基本的 XMLHttpRequest 开始,逐步了解并掌握 jQuery、fetch 和 Axios 这几种常用的前端网络请求方式。每种方式都有其特点和适用场景,希望通过本文的介绍,你能找到最适合项目的解决方案。

1.1 XMLHttpRequest

浏览器对XMLHttpRequest对象的支持度不足, 创建 XMLHttpRequest 对象时需要对IE浏览器做的兼

容解决。 - ActiveXObject

回顾:XHR

  • readyState
  • 0-4,0表示未初始化,4表示请求已完成
  • status(HTTP响应状态码)
    • 200:OK,成功
    • 3XX【重定向系列的状态码】
      • 301:永久重定向
      • 302:临时重定向
      • 307:内部浏览器(缓存)重定向
    • 4XX【错误系列】
      • 400:bad request,错误请求
      • 401:鉴权失败
      • 403:禁止访问
      • 404:找不到对应的资源
      • 405:方法不被允许
    • 5XX【服务器错误,环境问题】
      • 500:服务器内部错误(代码、环境问题)
      • 502:bad Getway,错误网关
    使用XHR请求全国高校数据接口
    接口地址
    • https://api.i-lynn.cn/college
    • 只循环展示 list 信息即可
    • 接口可以直接被跨域请求
    案例效果

参考代码:

  • <!DOCTYPE html>
  • <html lang="en">
  • <head>
  •  <meta charset="UTF-8">
  •  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  •  <title>Document</title>
  • </head>
  • <body>
  •  <div id="app"></div>
  • </body>
  • <script>
  •  // 1.生成XHR对象
  •  var xhr = new XMLHttpRequest()
  •  // 2.绑定回调函数
  •  xhr.onreadystatechange = function () {
  •    // 3. 判断是否成功
  •    if (xhr.readyState === 4 && xhr.status === 200) {
  •      const list = JSON.parse(xhr.responseText).data
  •      console.log(list)
  •   }
  • }
  •  // 4. 打开请求
  •  xhr.open('GET', 'https://api.i-lynn.cn/college')
  •  // 5.发送请求
  •  xhr.send()
  • </script>
  • </html>

1.2 jQuery

jQuery类的引入解决自己写兼容的烦恼,但现在只是使用了jQuery库中的网络请求功能,而jQuery中大量的dom的方法都是无效引入了,有点大材小用的意思。

  • $.ajax({
  •  url,
  •  type:get/post,
  •  data,
  •  dataType:json/text/xml/html/jsonp
  •  success:function(res){},
  •  error:function(){}
  • })
  • $.get(url,data,callback,dataType)
  • $.post(url,data,callback,dataType)
  • <!DOCTYPE html>
  • <html lang="en">
  • <head>
  •  <meta charset="UTF-8">
  •  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  •  <title>Document</title>
  • </head>
  • <body>
  •  <div id="app">
  •    <ul>
  •      <li v-for="(item,index) of list" :key = "index">{{ item.area }}</li>
  •    </ul>
  •  </div>
  • </body>
  • <script src="lib/jquery.min.js"></script>
  • <script src="lib/vue.js"></script>
  • <script>
  •  new Vue({
  •    el: '#app',
  •    data: {
  •      list: []
  •   },
  •    async mounted () {
  •      // async await
  •      // async 加载函数上,表示函数内部有异步操作
  •      // await 记载异步操作前,把异步操作写为同步
  •      const res = await $.get("https://api.i-lynn.cn/college", 'json')
  •      console.log(res)
  •      this.list = res.data.list
  •   }
  • })
  • </script>
  • </html>

async:关键词,用于函数声明关键词 function 之前,标记当前的函数为异步函数

await:关键词,让当前关键词的行代码执行之后等到到结果之后再去执行后续代码

1.3 fetch

由HTML5提供的内置API

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

基于Promise实现

fetch支持很多请求方式,但默认为 GET 请求,如果需要使用其他方式可以通过第二个自选参数的 method 选项去指定

  • fetch(url[,some settings]).then(fn2) .then(fn3) ... .catch(fn)
  • // 通过url表达式来传递数据
  • fetch("http://xxx/?id=123")
  • .then(res => res.json())
  • .then(data => console.log(data));
  • // post标准提交
  • fetch("http://xxxx/post", {
  •  method: "post",
  •  body: "uname=lisi&pwd=123",
  •  headers: { "Content-Type": "application/x-www-form-urlencoded"
  •           }
  • })
  • .then(res => res.json())
  • .then(data => console.log(data));
  • // post提交json数据
  • fetch("http://localhost:3000/books", {
  •  method: "post",
  •  body: JSON.stringify({ uname: "lisi", pwd: "123", }),
  •  headers: { "Content-Type": "application/json", }
  • })
  • .then(res => res.json())
  • .then(data => console.log(data));

注意:fetch 不会发送 cookies。除非你使用了credentials 的初始化选项 credentials: "include"

在上述代码示例中我们会看到有个 json() 方法,它是fetch的响应结果处理方法,fetch的常用响应

结果处理方法有:

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

使用fetch方式改写 XHR 部分案例

  • <!DOCTYPE html>
  • <html lang="en">
  • <head>
  •  <meta charset="UTF-8">
  •  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  •  <title>06 fetch</title>
  • </head>
  • <body>
  •  <div id="app">
  •    <ul>
  •      <li v-for="item of list" :key="item.proid">
  •       {{ item.proname }}
  •      </li>
  •    </ul>
  •    <input type="text" v-model="loginname">
  •    <input type="text" v-model="password">
  •    <button @click="login">登录</button>
  •  </div>
  • </body>
  • <script src="lib/vue.js"></script>
  • <script>
  •  new Vue({
  •    el: '#app',
  •    data: {
  •      list: [],
  •      loginname: '15635878563',
  •      password: '123456'
  •   },
  •    mounted () {
  •      // get请求
  •      fetch('http://182.44.11.110/api/pro/list?limitNum=1')
  •       .then(res => res.json()) // 需要把promise的对象转换为json对象
  •       .then(res => {
  •          console.log(res)
  •          this.list = res.data
  •       })
  •   },
  •    methods: {
  •      // post请求
  •      login () {
  •        fetch('http://http://182.44.11.110/api/user/login', {
  •          method: 'post',
  •          body: JSON.stringify({ loginname: this.loginname, password: this.password }),
  •          headers: {
  •            'Content-Type': 'application/json'
  •         }
  •       }).then(res => res.json())
  •         .then(res => {
  •            console.log(res)
  •         })
  •     }
  •   }
  • })
  • </script>
  • </html>

1.4 axios

1.4.1 基本使用

文档:https://www.kancloud.cn/yunye/axios/234845

axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和node.js中。axios是vue作者推荐使用

的网络请求库,它具有以下特性:

  • 支持浏览器和node.js
  • 支持promise
  • 能够拦截 请求和响应
  • 自动转换json数据

axios的浏览器支持

在使用axios之前需要在对应的模板文件中引入axiosjs库文件,随后按照以下用法使用axios:

  • // GET请求方式
  • axios.get('/get_data?id=10010')
  • .then(ret => console.log(ret.data))
  • axios.get('/get_data',{
  •  params: {
  •    id: 10010,
  •    name: 'zhangsan',
  •    age: 26 } })
  • .then(ret => console.log(ret.data))
  • //POST请求方式
  • axios.post('/set_data', {
  •  firstName: 'zhang', lastName: 'san'
  • }).then(ret => { })
  • axios({
  •  method: 'post',
  •  url: 'set_data',
  •  timeout: 1000,
  •  headers: {'X-Custom-Header': 'foobar'},
  •  data: { firstName: 'zhang', lastName: 'san' }
  • }).then(ret => { })

当然axios除了支持传统的 GET 和 POST 方式以外,常见的请求方式还支持:

  • put:修改数据
  • delete:删除数据

以上方的axios请求示例为例,axios响应结果( ret )的主要属性有:

  • data:实际响应回来的数据(最常用)**
  • headers:响应头信息
  • status:响应状态码
  • statusText:响应状态信息

另外需要注意的是,在使用axios发送请求之前它允许我们通过全局配置做一些设置,这样可以方便后续的请求操作,例如:

  • axios.defaults.timeout = 3000【设置超时时间】
  • axios.defaults.baseURL = 'http://localhost/app'【设置默认地址】
  • axios.defaults.headers['token'] = '123123123'【设置请求头信息,通用头信息】
    • axios.defaults.headers.get['_token'] = '123123'
    • axios.defaults.headers.post['_token'] = '123123'
    • axios.defaults.headers.common['_token'] = '123123'【通用头信息,common可以不写】

注意:

axios发送post请求的时候,默认发送json格式数据

如果需要发送post表单类型请求,则需要指定请求头

  • axios.post('college',{
  •  username: 'zhangsan', age: 22
  • },{
  •  headers: { "Content-Type": "application/x-www-form-urlencoded" }
  • }).then(ret => this.list = ret.data.list)

使用axios方式改写 XHR 部分案例

  • <!DOCTYPE html>
  • <html lang="en">
  • <head>
  •  <meta charset="UTF-8">
  •  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  •  <title>07 axios</title>
  • </head>
  • <body>
  •  <div id="app">
  •    <ul>
  •      <li v-for="item of list" :key="item.proid">
  •       {{ item.proname }}
  •      </li>
  •    </ul>
  •    <input type="text" v-model="loginname">
  •    <input type="text" v-model="password">
  •    <button @click="login">登录</button>
  •  </div>
  • </body>
  • <script src="lib/vue.js"></script>
  • <script src="lib/axios.min.js"></script>
  • <script>
  •  // http://121.89.205.189/apidoc/
  •  new Vue({
  •    el: '#app',
  •    data: {
  •      list: [],
  •      loginname: '18813007814',
  •      password: '123456'
  •   },
  •    mounted () {
  •      // get请求
  •      // fetch('http://182.44.11.110/api/pro/list?limitNum=1')
  •      //   .then(res => res.json()) // 需要把promise的对象转换为json对象
  •      //   .then(res => {
  •      //     console.log(res)
  •      //     this.list = res.data
  •      //   })
  •      // axios.get('http://182.44.11.110/api/pro/list')
  •      //   .then(res => {
  •      //     console.log(res)
  •      //     this.list = res.data.data
  •      //   })
  •      // axios.get('http://182.44.11.110/api/pro/list?limitNum=2')
  •      //   .then(res => {
  •      //     console.log(res)
  •      //     this.list = res.data.data
  •      //   })
  •      axios.get('http://182.44.11.110/api/pro/list', { // 推荐使用他传递参数
  •        params: {
  •          limitNum: 3
  •       }
  •     })
  •       .then(res => {
  •          console.log(res)
  •          this.list = res.data.data
  •       })
  •   },
  •    methods: {
  •      // post请求
  •      login () {
  •        // fetch('http://182.44.11.110/api/user/login', {
  •        //   method: 'post',
  •        //   body: JSON.stringify({ loginname: this.loginname, password: this.password }),
  •        //   headers: {
  •        //     'Content-Type': 'application/json'
  •        //   }
  •        // }).then(res => res.json())
  •        //   .then(res => {
  •        //     console.log(res)
  •        //   })
  •        axios.post('http://182.44.11.110/api/user/login', {
  •          loginname: this.loginname,
  •          password: this.password
  •       }).then(res => {
  •          console.log(res)
  •       })
  •     }
  •   }
  • })
  • </script>
  • </html>
1.4.2 拦截器

目的:在请求 发出去之前 / 收到响应之后 做一些操作

请求拦截器

  • axios.interceptors.request.use(function(config){
  •  // 在请求发出去之前进行一些信息设置
  •  return config;
  • },function(err){
  •  // 处理响应的错误信息
  • });

响应拦截器

  • axios.interceptors.response.use(function(res){
  •  // res为axios对象
  •  return res;
  • },function(err){
  •  // 处理响应的错误信息
  • });
  • <!DOCTYPE html>
  • <html lang="en">
  • <head>
  •  <meta charset="UTF-8">
  •  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  •  <title>Document</title>
  • </head>
  • <body>
  •  <div id="app">
  •    <ul>
  •      <li v-for="(item,index) of list" :key = "index">{{ item.area }}</li>
  •    </ul>
  •  </div>
  • </body>
  • <script src="lib/vue.js"></script>
  • <script src="lib/axios.min.js"></script>
  • <script>
  •  axios.interceptors.request.use(function(config){
  •    // 在请求发出去之前进行一些信息设置
  •    console.log('loading......')
  •    return config;
  • },function(err){
  •    // 处理响应的错误信息
  • });
  •  axios.interceptors.response.use(function(res){
  •    // res为axios对象
  •    console.log('loading end')
  •    return res;
  • },function(err){
  •    // 处理响应的错误信息
  • });
  •  new Vue({
  •    el: '#app',
  •    data: {
  •      list: []
  •   },
  •    mounted () {
  •      // axios.get('https://api.i-lynn.cn/college')
  •      //   .then(res => {
  •      //     console.log(res)
  •      //     this.list = res.data.data.list
  •      //   })
  •      axios({
  •        url: 'https://api.i-lynn.cn/college',
  •        method: 'GET',
  •        headers: {
  •          'content-type': 'application/json'
  •       }
  •     }).then(res => {
  •        console.log(res)
  •        this.list = res.data.data.list
  •     })
  •   }
  • })
  • </script>
  • </html>
总结

通过本文的介绍,我们从最基础的 XMLHttpRequest 逐步过渡到了现代的 Axios,每一种请求方式都有其独特的优势和适用场景。XMLHttpRequest 虽然历史悠久,但依然在某些场景下有其价值;jQuery 简化了兼容性问题,但引入了额外的库;fetch 是原生的现代 API,简洁且功能强大;Axios 则是 Vue 官方推荐的库,支持 Promise,使用起来非常方便。希望本文能帮助你在实际项目中选择合适的网络请求方式。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐