Skip to content

Ajax 入门与 axios 基本使用 ​

本页对应 1-1Ajax介绍和axios基本使用,共 6 段视频,约 1 小时 2 分。

学习目标 ​

  • 能说明 AJAX 的作用,并独立使用 axios 发送 GET 请求,通过 res.data 获取服务器返回数据。
  • 能拆解 URL 的协议、域名和资源路径,指出各组成部分在请求中的作用。
  • 能使用 axios 的 params 传递一个或多个 URL 查询参数,并说明查询参数在 URL 中的拼接格式。
  • 能完成省市区查询案例:获取输入框内容,传递多个查询参数,并使用 map、join、innerHTML 将数据渲染为列表。
  • 能使用 method 和 data 发送 POST 请求提交数据,并使用 catch 捕获错误、读取响应信息并通过弹框提示用户。

知识点 ​

AJAX 是什么 ​

为什么需要:以前页面数据常写死在代码里,想换数据就得改代码;实际项目的数据往往来自服务器,需要浏览器主动向服务器要数据。
怎么想:先记住 AJAX 不是某个具体库,而是一种“浏览器与服务器通信”的技术;本节先接触它的常见底层对象 XMLHttpRequest,再用更简单的 axios 上手。
怎么做:AJAX 可理解为使用浏览器的 XMLHttpRequest 对象与服务器通信。服务器暂时理解为“在互联网上提供数据的一台电脑”。
易错点:不要把 AJAX 和 axios 混为一谈:AJAX 是通信技术/概念,axios 是封装好的请求库;转写稿里“小黄人对象”是 XHR 的戏称,正式名称是 XMLHttpRequest。

为什么学 AJAX ​

为什么需要:固定写死的数据无法随时变化,页面就“死”了;从服务器获取数据后,数据才能变活。
怎么想:本节先不急着研究底层原理,而是先能发出请求、拿到数据、渲染页面,建立“浏览器请求服务器—服务器返回数据—页面使用数据”的完整链路。
怎么做:明确数据来源从“自己定义假数据”变为“服务器提供数据”;事件绑定、DOM 操作等代码基本不变,变的是数据来源。
易错点:不要以为学了 AJAX 就要重写所有页面逻辑;本节重点是新增“请求数据”的步骤。

学习路线与 axios 的定位 ​

为什么需要:直接学 XMLHttpRequest 语法较繁琐,初学者容易把精力耗在底层细节上。
怎么想:先用第三方库 axios 快速完成通信,后续再学 XMLHttpRequest 了解 AJAX 底层原理;Vue、React 学习中也会使用 axios。
怎么做:本节先掌握 axios 的基本使用:引入库,调用 axios 函数,在 then 中接收并处理数据。
易错点:axios 是库,使用前必须先引入;不要漏掉 <script> 的 src。

引入 axios ​

为什么需要:页面本身不认识 axios,必须先加载库文件,页面上才会多出可调用的 axios 函数。
怎么想:先导包,再写业务逻辑;如果第一个 CDN 加载不了,就换第二个。
怎么做:把下面地址设置到 script 标签的 src 中:

https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js
https://cdn.bootcdn.net/ajax/libs/axios/1.3.4/axios.min.js

易错点:引入 axios 的 script 要放在使用它的业务 script 之前;网络原因加载失败时换备用地址。

axios 基本语法 ​

为什么需要:我们需要用统一、简单的方式告诉 axios“请求哪个地址”,并处理服务器返回结果。
怎么想:核心两步:发请求、接收并使用数据。url 是目标资源地址;then 先体验使用,后续再讲由来。
怎么做:

js
axios({
  url: '目标资源地址'
}).then((result) => {
  // 对服务器返回的数据做后续处理
})

易错点:then 不要拼错;回调函数要定义形参,否则拿不到结果;请求的 url 是标记资源的网址,不是随便写的字符串。

案例:获取省份列表并渲染 ​

为什么需要:只看语法没有体感,需要通过“点击按钮获取省份数据并展示”验证完整流程。
怎么想:先给按钮绑定点击事件,再调用 axios 请求 http://hmajax.itheima.net/api/province,最后把数据渲染到 .province。
怎么做:完成效果如下:

省份列表渲染效果

对应代码:

html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>AJAX介绍及axios基本使用</title>
</head>

<body>
  <p class="province">
    <!-- 数据渲染到这里 -->
  </p>
  <button class="btn">渲染省份数据</button>
  <!-- 
      axios库地址: https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js
      省份数据地址: http://hmajax.itheima.net/api/province
      需求: 点击按钮 通过 axios 获取省份数据 并渲染
    -->
  <!-- 使用axios记得先导包 -->
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    document.querySelector('.btn').addEventListener('click', () => {
      // console.log('点了按钮')
      // 通过 axios 获取省份数据 并渲染
      // 1. 调用axios函数
      axios({
        url: 'http://hmajax.itheima.net/api/province'
      }).then(res => {
        // 2. 接收并使用数据
        // console.log(res)
        // res.data 可以获取服务器返回的数据
        // console.log(res.data)
        console.log(res.data.list)
        document.querySelector('.province').innerText = res.data.list
      })

    })
  </script>
</body>

</html>

易错点:转写稿调试时先 console.log('点了按钮') 确认点击事件绑定成功,再写请求;打印 res 会发现 axios 把服务器数据包了一层,真正数据在 res.data,省份数组在 res.data.list;不要写成 res.list。本节用 innerText 渲染文本,后续再学列表结构渲染。

调试过程与小结 ​

为什么需要:请求代码容易“看起来对但页面没反应”,需要按步骤定位。
怎么想:先确认事件是否触发,再确认 axios 是否引入,再打印 res、res.data、res.data.list,逐层确认数据。
怎么做:AJAX 用于浏览器和服务器通信、动态数据交互;学习路线是先掌握 axios 使用,再了解 XMLHttpRequest 原理;本节 axios 体验步骤是“引入 axios 库,使用 axios 相关语法”。
易错点:忘记导包、地址写错、漏写 then 形参、误把 res 当服务器数据、把 innerText 写成 innerTest,都会导致拿不到或渲染不了数据。

本节目标与学习思路 ​

这一节要弄清两件事:URL 是什么,以及 URL 由哪些关键部分组成。上一节用 axios 请求省份数据时,地址是直接复制来的;但实际开发中,后端给的是一个网址,我们必须知道哪一部分代表服务器、哪一部分代表资源,才能和服务器有效沟通。学习时不要只背定义,而要拿一个真实地址拆开看:先找协议,再找域名,最后找资源路径。易错点是:把整个网址当成“一个普通字符串”,不知道各段作用。

什么是 URL ​

URL 叫统一资源定位符,简称网址,用于定位网络中的资源。资源可以是网页、图片、数据、视频、音频等。转写稿中通过三个地址验证:打开黑马程序员官网是网页资源,打开 logo 是图片资源,打开数据接口得到 JSON 数据资源。这说明 URL 不只是“网页地址”,也可以定位图片和数据。

为什么需要:浏览器要知道“去哪个服务器、拿什么资源”。怎么想:把 URL 看成“通信地址”。怎么做:遇到一个 URL,先整体访问确认资源类型,再拆分结构。易错点:不要把 URL 只理解成网页链接;数据接口也是 URL。

URL 的三个重要组成部分 ​

一个完整 URL 有很多组成部分,本节先掌握三个:协议、域名、资源路径,格式可记为:

text
协议://域名/资源路径

例如:

text
http://hmajax.itheima.net/api/news

其中 http 是协议,hmajax.itheima.net 是域名,/api/news 是资源路径。转写稿还举例:/api/province 是省份数据,/api/city 是城市数据,/api/news 是新闻数据;资源和路径的对应关系由服务器决定。若把域名换成百度,就拿不到黑马服务器上的省份、城市数据。

为什么需要:不拆分就无法理解请求目标。怎么想:从左往右读,“用什么规则通信 → 找哪台服务器 → 要服务器里的哪个资源”。怎么做:先找 :// 前是协议,:// 后到第一个 / 前是域名,后面的路径是资源路径。易错点:不要把域名和资源路径混在一起;资源路径不是本地文件路径。

HTTP 协议、域名、资源路径分别做什么 ​

HTTP 叫超文本传输协议,规定了浏览器和服务器传递数据的格式。具体格式后续章节会学,本节先记住:协议规定内容格式。域名标记服务器在互联网中的方位;网络中有很多服务器,你想访问哪一台,就需要知道它的域名。资源路径用于标识你要访问的资源在服务器内的具体位置。

为什么需要:协议保证双方“按同一格式说话”,域名解决“找哪台服务器”,路径解决“找哪个资源”。怎么想:三者分别回答“怎么通信、找谁、要什么”。怎么做:读 URL 时分别标注。易错点:不要漏写 http://;常见协议还有 HTTPS,但本节案例使用 HTTP;域名不是资源名。

案例:访问新闻列表并打印数据 ​

需求:访问新闻列表的 URL,打印新闻数据。新闻列表数据 URL 为:

text
http://hmajax.itheima.net/api/news

笔记代码:

js
axios({
  url: 'http://hmajax.itheima.net/api/news'
}).then(result => {
  console.log(result)
})

效果图如下:

新闻列表数据打印效果图

转写稿中的调试过程是:先在浏览器打开该 URL,确认返回 JSON 数据;再在页面中给按钮绑定点击事件,确认点击事件正常;然后调用 axios,在 then 回调里接收结果。直接打印 result 会发现它是 axios 包装后的对象,服务器返回的数据在 result.data 中,因此可继续调试:

js
axios({
  url: 'http://hmajax.itheima.net/api/news'
}).then(result => {
  console.log(result.data)
})

展开后能看到提示信息和新闻数组。这里的 URL 可解释为:从黑马服务器使用 HTTP 协议,访问 /api/news 路径下的新闻列表资源。

为什么需要:把 URL 知识落到真实请求中。怎么想:地址决定请求目标,回调接收响应。怎么做:先验证 URL,再发请求,再打印 result.data 查看服务器数据。易错点:不要误以为 result 就是服务器原始数据;不要漏写协议;路径写错会拿不到对应资源。

小结 ​

URL 是统一资源定位符,也就是网址,用于访问服务器上的资源。http://hmajax.itheima.net/api/news 可拆为“协议://域名/资源路径”:http 是协议,hmajax.itheima.net 是域名,/api/news 是资源路径。协议规定传递数据格式,域名定位服务器,资源路径定位服务器内资源。

目标:通过URL传递查询参数,获取匹配的数据 ​

为什么需要:服务器上的数据通常很多,比如城市列表会包含全国数据。如果每次都把全部数据返回,既浪费带宽,也不方便前端筛选。我们真正想要的是“某个省下面的城市”,所以必须把“省份”这个额外信息告诉服务器。
怎么想:浏览器和服务器通信时,除了URL里的协议、域名、资源路径,还可以在URL末尾追加查询参数。服务器根据参数找到对应数据再返回。
怎么做:先认识查询参数语法,再用axios的params选项传递。
易错点:参数名不是前端随便起的,一般由后端规定;问号、等号、&都不能随意漏写。

查询参数是什么、语法怎么写 ​

为什么需要:以查询城市列表为例,接口地址是http://hmajax.itheima.net/api/city,但服务器还需要知道查哪个省。转写稿中用百度举例:带查询参数的URL点开后,可以直接出现“黑马程序员”或“传智播客”的搜索结果,说明查询参数会把额外信息带给服务器。
怎么想:把查询参数理解成“键值对列表”。格式是:?参数名=值&参数名2=值2。问号用来分隔资源路径和查询参数,多个参数之间用&连接,键和值之间用=连接。
怎么做:本节接口规定参数名是pname,值传省份或直辖市名,例如?pname=河北省。如果只写http://hmajax.itheima.net/api/city而不带pname,服务器不知道查哪里,会返回提示信息,提醒需要pname和省份名字。
易错点:问号不能省;参数之间不要写空格;不要漏掉等号;参数名大小写要按后端要求写。

axios 如何携带查询参数 ​

为什么需要:虽然可以手动把?pname=湖北省拼到URL后面,但实际开发中参数一多就容易漏问号、漏等号或漏&。转写稿也强调:开发中一般用params,不需要自己拼接字符串,避免出错。
怎么想:axios把“请求地址”和“查询参数”分开配置。地址放在url,查询参数放在params对象里,axios会自动拼接到URL末尾并保证格式。
怎么做:

javascript
axios({
  url: 'http://hmajax.itheima.net/api/city',
  params: {
    pname: '湖北省'
  }
}).then(res => {
  console.log(res.data)
})

调试时可以先console.log(res),会发现axios把服务器返回内容包装在res.data里;再打印res.data,就能看到message和城市数组list。
易错点:查询参数用params,不是提交数据用的data;GET请求的method可以省略;取服务器数据要记得用res.data。

完整示例:获取指定省份城市列表 ​

为什么需要:把上面的语法放进真实页面,验证点击按钮后能否携带pname拿到对应省份城市。
怎么想:先给按钮绑定点击事件,再在事件里调用axios,用params传pname,最后在then里接收并使用数据。
怎么做:保留笔记代码如下。

html
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <button class="btn">获取城市数据并渲染</button>
  <!-- 1. 导包 -->
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <!-- 
    城市数据:http://hmajax.itheima.net/api/city
      获取某个省所有的城市
      查询参数名:pname
      说明:传递省份或直辖市名比如 北京、广东省…
    需求: 点击按钮 通过axios 获取某个省的城市 并输出
  -->
  <script>
    document.querySelector('.btn').addEventListener('click', function () {
      // console.log('点了按钮哦')
      // 通过axios 获取某个省的城市 并输出
      axios({
        // url: 'http://hmajax.itheima.net/api/city?pname=湖南省',
        url: 'http://hmajax.itheima.net/api/city',
        // 开发中 一般用params 不需要自己拼接字符串避免出错
        params: {
          pname: '湖北省'
        }
      }).then(res => {
        console.log(res.data)
      })
    })
  </script>

</body>

</html>

易错点:按钮类名要写对;axios导包要在业务代码前;params里键名是pname;省份名要传服务器能识别的值。转写稿中还演示了换成“湖南省”也能查询成功,说明改变参数值就能拿到不同省份数据。

小结:查询参数与axios配置 ​

为什么需要:查询参数让同一个接口根据不同的值返回不同数据。
怎么想:URL负责定位资源和服务器,查询参数负责补充筛选条件。
怎么做:URL语法用?参数名=值&参数名2=值2;axios用params对象携带。
易错点:不要手拼字符串导致格式错误;不要混淆params和data;不要忘记从res.data取服务器返回数据。

需求与接口理解 ​

为什么需要: 省市区查询是常见业务场景,例如设置个人资料、填写收货地址。本节只聚焦最后一步:根据输入的省份和城市,查询该城市下属的地区列表。

怎么想: 先明确接口和参数。查询地区接口是 http://hmajax.itheima.net/api/area,需要传两个查询参数:pname 表示省份或直辖市名,例如“北京”“湖北省”;cname 表示省份内的城市,例如“北京市”“武汉市”。两者有包含关系,不能随意组合。

怎么做: 完成效果如下图所示:

地区查询效果图

易错点: pname 和 cname 的命名要与后端约定一致;直辖市场景下也要按示例传“北京 / 北京市”这类对应关系,不要自己臆造参数名。

获取输入框内容并确认 ​

为什么需要: 查询依赖用户输入的省份名和城市名,必须先从输入框取值。

怎么想: 先给查询按钮绑定点击事件,再分别读取 .province 和 .city 的 value。转写稿中的调试顺序很值得保留:先 console.log('点了按钮哦!') 确认点击事件绑定成功,再打印 pname、cname 确认取值正确。

怎么做:

js
document.querySelector('.my-button').addEventListener('click', function () {
  const pname = document.querySelector('.province').value
  const cname = document.querySelector('.city').value
  console.log('pname:', pname)
  console.log('cname:', cname)
})

易错点: 选择器类名前的点不能漏;取输入框内容要用 value;不要一上来就写请求,先用打印确认点击和取值都正常。

用 params 传递多个查询参数 ​

为什么需要: 查询参数如果手动拼到 URL 上,容易漏问号、等号或 &。axios 提供 params 配置,可以自动拼接并保证格式。

怎么想: 把 pname、cname 放进 params 对象中,多个键值对用逗号隔开。请求成功后,服务器返回的数据在 res.data 中,地区数组在 res.data.list。

怎么做:

js
axios({
  url: 'http://hmajax.itheima.net/api/area',
  params: {
    pname,
    cname
  }
}).then(res => {
  const list = res.data.list
  console.log('list:', list)
})

易错点: 属性名是 params,不是 pars;多个参数之间要有逗号;不要忘记 res.data.list 的层级,先打印确认再渲染。

查询结果渲染为列表 ​

为什么需要: 接口返回的是数组,页面需要的是多个 <li> 列表项,因此要把数组转换成 HTML 字符串。

怎么想: 用 map 把每个地区名映射成一个 <li>,得到 HTML 字符串数组;再用 join('') 拼成一个完整字符串;最后用 innerHTML 设置到 .list-group 中,让浏览器解析标签。

怎么做:

js
const htmlArr = list.map(v => `<li class="list-group-item">${v}</li>`)
console.log('htmlArr:', htmlArr)
document.querySelector('.list-group').innerHTML = htmlArr.join('')

易错点: 模板字符串要用反引号;join() 要传空字符串 '',否则列表项之间会出现逗号;设置 HTML 结构用 innerHTML,不要用 innerText。转写稿中正是先打印 list、再打印 htmlArr,发现逗号问题后用 join('') 解决。

代码整理与 ES6 简写 ​

为什么需要: 当对象属性名和变量名同名时,可以简写,减少重复代码。

怎么想: params 中原本可以写成 pname: pname, cname: cname,因为变量名和属性名相同,所以可以简写成 { pname, cname }。

怎么做: 完整代码如下:

js
/*
  http://hmajax.itheima.net/api/area
  传递某个省份内某个城市的所有区县
  查询参数名:pname、cname
  pname说明:传递省份或直辖市名,比如 北京、湖北省…
  cname说明:省份内的城市,比如 北京市、武汉市…
  核心功能:查询地区,并渲染列表
*/
document.querySelector('.my-button').addEventListener('click', function () {
  // console.log('点了按钮哦!')

  // 1.获取输入框的内容
  const pname = document.querySelector('.province').value
  const cname = document.querySelector('.city').value
  console.log('pname:', pname)
  console.log('cname:', cname)

  // 2.查询地区,并渲染列表
  axios({
    url: 'http://hmajax.itheima.net/api/area',
    params: {
      pname, cname // pname: pname,
      // cname: cname
    }
  }).then(res => {
    // console.log(res.data)
    const list = res.data.list
    // console.log('list:', list)
    const htmlArr = list.map(v => `<li class="list-group-item">${v}</li>`)
    // console.log('htmlArr:', htmlArr)
    document.querySelector('.list-group').innerHTML = htmlArr.join('')
  })
})

易错点: 只有属性名和变量名同名才能简写;不同名时仍要写 属性名: 变量名。

小结 ​

本节巩固了查询参数和多个参数的传递方式:先用 params 传 pname、cname,再从 res.data.list 取数组,用 map 生成 <li> 数组,用 join('') 拼接,最后通过 innerHTML 渲染。ES6 对象属性和值简写的前提是:属性名和 value 位置的变量名同名。

先认识请求方法:GET 与 POST ​

为什么需要:前面我们获取省份、新闻等数据,其实都是在向服务器“要数据”。但实际开发不只要拿数据,还要把浏览器里的数据交给服务器保存,例如注册、登录、下单。要区分“查数据”和“交数据”,就要认识 HTTP 协议规定的请求方法。

怎么想:请求方法是一些固定英文单词,每个单词代表对服务器资源的一种操作。常用的是 GET 和 POST:GET 查询数据,POST 提交数据。前面获取数据时没写方法,是因为 axios 默认请求方法就是 GET。

请求方法示意图

怎么做:先记住两个最常用方法:GET 用于查询,POST 用于提交;其他如 PUT、DELETE、PATCH 了解即可,后续课程再展开。

易错点:不要把所有请求都写成 GET;GET 适合查询,不适合把需要保存的数据提交到服务器。请求方法虽然是固定单词,大小写不区分,但代码中建议统一写小写,如 method:'post'。

什么时候要把数据提交到服务器 ​

为什么需要:如果订单、用户名和密码只存在浏览器本地,换一台设备或换一个浏览器就看不到、登不上。只有保存到服务器,才能多端访问同一份数据。

怎么想:判断标准是:这份数据是否要“存起来并随时再访问”。例如多端查看同一订单、同一账号登录、注册用户信息,都需要提交到服务器。

怎么做:把要保存的数据作为请求体提交给服务器;学习阶段由接口文档告诉我们 URL、请求方法和参数名,实际工作中由后端工程师提供。

易错点:不要把“查询参数”和“提交数据”混为一谈。查询参数通常拼在 URL 上,用于筛选;提交的数据放在请求体里,用于保存。字段名要按接口要求写,不能自己改名。

axios 提交数据的两个新配置:method 和 data ​

为什么需要:axios 默认用 GET,只会“查”。要提交数据,必须显式告诉 axios 用 POST,并把数据放进请求体。

怎么想:在原有 url 基础上,新增两个核心配置:method 设置请求方法,data 设置提交的数据。data 最常用对象键值对形式,键由后端规定,值是要提交的内容。

怎么做:通用写法如下,保留本节笔记代码:

javascript
axios({
  url:'请求URL',
  method:'post',
  data:{
    key:'value'
  },
})

易错点:method 不要拼错;提交数据用 data,不要写成查询参数 params;data 里的键名要按接口文档写。转写稿里说的“mus / ma的”其实是 method,“date”其实是 data,写代码时以英文配置名为准。

注册账号案例:把用户名和密码 POST 到服务器 ​

为什么需要:注册是把用户信息保存到服务器的典型场景。只会在控制台打印不够,要真正发出 POST 请求,并观察服务器返回结果。

怎么想:需求是“注册账号,提交用户名和密码到服务器保存”。接口为:URL http://hmajax.itheima.net/api/register,请求方法 POST,参数 username(中英文和数字组成,最少8位)、password(最少6位)。因此 method 写 'post',data 中放 username 和 password。

怎么做:先给按钮绑定点击事件,确认能触发;再在点击回调里调用 axios。示例中用户名请替换为满足至少8位要求的值:

javascript
axios({
  url: 'http://hmajax.itheima.net/api/register',
  method: 'post',
  data: {
    username: '填写至少8位的用户名',
    password: '123456'
  }
}).then(res => {
  console.log(res.data)
})

调试时先点按钮,确认点击事件生效;再提交,打印 res.data 可看到服务器返回的提示信息,转写稿中显示“注册成功”。如果重复提交同一个用户名,服务器会返回“账号被占用”一类错误,说明数据确实已存到服务器;错误处理下一节再讲。转写稿中的“exs / acts”都是 axios,“IES”指 res,“z”指 then。

易错点:用户名、密码长度要符合接口要求;username、password 拼写不能错;提交数据放 data,不要放 params;不要用 GET 做注册提交。

小结:核心配置与常见混淆 ​

为什么需要:把本节和前面知识串起来,才能在实际接口中快速判断该用 GET 还是 POST、该写哪些配置。

怎么想:请求方法最常用的是 POST 和 GET:POST 提交数据,GET 查询数据。axios 核心配置目前是:url 目标资源地址、method 请求方法、params 查询参数、data 提交的数据。

怎么做:查数据用 GET,method 可省略;提交保存用 POST,必须写 method:'post',并把数据放进 data。查询参数放 params,提交数据放 data。

易错点:params 和 data 最容易混;GET 省略方法不代表只能 GET;POST 提交时字段名、数据格式要按接口文档来。

目标与错误场景 ​

为什么需要:注册相同用户名时,请求会失败。普通用户不会打开控制台看错误,所以必须把错误信息拿到并展示到页面上。

怎么想:先复现失败请求,观察控制台里的错误来源。转写稿中强调:重复注册后控制台会出现两个错误——第一个是浏览器接收到服务器错误后产生的,第二个是 axios 发现请求没有成功而产生的;axios 的错误信息里包含服务器返回内容,位置在 response.data。

怎么做:用相同用户名再次提交注册请求,观察控制台错误:

控制台中重复注册用户名时出现的请求失败错误

易错点:不要以为控制台里只有一个错误;本例中 catch 能处理的是 axios 产生的错误,浏览器自身产生的错误仍会显示在控制台。

用 catch 捕获错误并展示 ​

为什么需要:请求成功走 then,请求失败要有对应处理,否则用户看不到“账号被占用”等原因。

怎么想:axios 调用后可以链式调用 .then() 和 .catch()。成功逻辑写在 then,失败逻辑写在 catch;catch 的回调形参可接错误对象,本例中通过 err.response.data.message 取服务器提示。

怎么做:语法如下:

javascript
axios({
  // 请求选项
}).then(res => {
  // 处理数据
}).catch(err => {
  // 处理错误
})

对应代码:

js
document.querySelector('.btn').addEventListener('click', function () {
    // console.log('点了')
    // 通过axios提交用户数据,完成用户注册
    axios({
      url: 'http://hmajax.itheima.net/api/register',
      method: 'post',
      data: {
        username: 'itheima008',
        password: '123456'
      }
    }).then(res => {
      console.log(res.data)
    }).catch(err => {
      // 重复注册,通过弹框提示用户
      // console.log(err)
      // console.log(err.response.data)
      alert(err.response.data.message)
    })
  })

易错点:只写 console.log(err) 普通用户看不到;要按层级取 err.response.data.message;弹框用 alert,不是“弹簧”。

调试过程与验证 ​

为什么需要:确认 catch 是否真的执行、取到的提示是否就是服务器返回内容。

怎么想:先加 catch 并输出 err,再逐层查看 response、data,最后用 alert 展示 message。

怎么做:转写稿中的调试过程是:加 .catch(err => { ... }) 后再次点击按钮,第二个 axios 错误不再以未处理形式出现;输出 err.response.data 能看到服务器返回内容;改为 alert(err.response.data.message) 后页面弹出“账号被占用”一类提示。此时控制台第一个浏览器错误仍可能存在,因为 catch 处理的是 axios 这一侧的错误。

易错点:不要把 catch 写成 catch() 后忘记形参;不要漏掉 response.data.message 的层级;验证时既要看控制台,也要看页面弹框。

小结 ​

axios 拿请求响应失败信息的方式是:在 axios 函数调用后继续调用 .catch 方法捕获。成功走 then,失败走 catch;本例用 alert(err.response.data.message) 把服务器返回的错误原因展示给用户。

课件图示 ​

课件第22页:使用axios传递查询参数 通过params属性设置对象的方式传递 axios(

课件第23页:试一试 需求:点击按钮通过axios 获取某个省份的城市,并输出 请求地址(ur

课件第24页:总结 总结 1. URL查询参数: 查询参数是提供给网络服务器的额外参数 2.

课件第29页:总结 总结 1. 如何通过axios传递多个查询参数? 2. ES6对象属性赋值

课件第35页:总结 总结 1. 请求方法表明对服务器资源的操作,最为常用的是? POST提交数

代码示例 ​

示例 1:axios 基本使用 —— 获取省份数据并渲染 ​

html
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>AJAX介绍及axios基本使用</title>
</head>

<body>
  <p class="province">
    <!-- 数据渲染到这里 -->
  </p>
  <button class="btn">渲染省份数据</button>
  <!-- 
      axios库地址: https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js
      省份数据地址: http://hmajax.itheima.net/api/province
      需求: 点击按钮 通过 axios 获取省份数据 并渲染
  -->
  <!-- 使用axios记得先导包 -->
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    document.querySelector('.btn').addEventListener('click', () => {
      // 1. 调用axios函数发请求
      axios({
        url: 'http://hmajax.itheima.net/api/province'
      }).then(res => {
        // 2. 接收并使用数据
        console.log(res.data.list)
        document.querySelector('.province').innerText = res.data.list
      })
    })
  </script>
</body>

</html>

关键行与易错点

  • 先 <script src="...axios.min.js"> 导包,再写业务代码;顺序反了会报 axios is not defined。
  • axios({ url: '...' }) 里 url 是固定属性名,值是从后端拿到的目标资源地址,不用自己拼。
  • 服务器返回的数据被 axios 包了一层,必须 res.data 才是真正的响应体,再 .list 才拿到省份数组。
  • then 后面的回调一定要定义形参(这里叫 res),漏写就拿不到数据。
  • 渲染纯文本用 innerText;如果数据里带 HTML 标签结构才用 innerHTML。
  • 事件绑定、操作 DOM 的写法和以前完全一样,变的只是“数据来源”。

示例 2:URL 查询参数 —— 省市区查询并渲染列表 ​

html
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>案例-查询地区列表</title>
</head>

<body>
  <input class="province" placeholder="省份/直辖市,如:湖北省" />
  <input class="city" placeholder="城市,如:武汉市" />
  <button class="my-button">查询地区</button>
  <ul class="list-group"></ul>

  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    /*
      http://hmajax.itheima.net/api/area
      传递某个省份内某个城市的所有区县
      查询参数名:pname、cname
      pname说明:传递省份或直辖市名,比如 北京、湖北省…
      cname说明:省份内的城市,比如 北京市、武汉市…
      核心功能:查询地区,并渲染列表
    */
    document.querySelector('.my-button').addEventListener('click', function () {
      // 1. 获取输入框的内容
      const pname = document.querySelector('.province').value
      const cname = document.querySelector('.city').value
      console.log('pname:', pname)
      console.log('cname:', cname)

      // 2. 查询地区,并渲染列表
      axios({
        url: 'http://hmajax.itheima.net/api/area',
        params: {
          pname, cname // ES6 简写:pname: pname, cname: cname
        }
      }).then(res => {
        const list = res.data.list
        const htmlArr = list.map(v => `<li class="list-group-item">${v}</li>`)
        document.querySelector('.list-group').innerHTML = htmlArr.join('')
      })
    })
  </script>
</body>

</html>

关键行与易错点

  • 查询参数用 params 选项传对象,axios 会自动拼成 ?pname=xx&cname=xx,不要自己在 url 后面手写问号和 &,容易漏符号出错。
  • 多个参数就在 params 对象里用逗号隔开多个键值对。
  • 属性名和变量名相同时才能用 ES6 简写 { pname, cname };名字不同时必须写 键: 值。
  • 输入框取内容用 .value,不是 innerText。
  • map 生成的是“字符串数组”,直接塞给 innerHTML 会出现多余逗号,必须 join('') 拼成一个完整字符串。
  • 模板字符串两边是反引号 `,不是单引号,否则 ${v} 不会被替换。

示例 3:POST 提交数据 + catch 错误处理(注册用户) ​

html
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>数据提交与错误处理</title>
</head>

<body>
  <button class="btn">注册用户</button>

  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script>
    document.querySelector('.btn').addEventListener('click', function () {
      // 通过axios提交用户数据,完成用户注册
      axios({
        url: 'http://hmajax.itheima.net/api/register',
        method: 'post',
        data: {
          // 用户名要求中英文和数字组成,最少8位;密码最少6位
          // 换成已注册过的用户名(如 itheima008)即可触发 catch 分支
          username: 'hm' + Date.now(),
          password: '123456'
        }
      }).then(res => {
        console.log(res.data)
        alert(res.data.message)
      }).catch(err => {
        // 重复注册,通过弹框提示用户
        console.log(err.response.data)
        alert(err.response.data.message)
      })
    })
  </script>
</body>

</html>

关键行与易错点

  • 提交数据要写 method: 'post';GET 是 axios 的默认方法,所以之前获取数据时没写也能用。
  • 提交的数据放 data(对象形式),查询参数放 params,两者别混:params 拼到 URL 上,data 放在请求体里。
  • 用户名/密码有格式要求(用户名 ≥8 位,密码 ≥6 位),不满足会走 catch。
  • 错误信息在 err.response.data 里,提示文字是 .message;直接 err.data 是取不到的。
  • .then().catch() 是链式调用:成功进 then,失败进 catch,注意 catch 写在 then 后面。
  • 控制台里仍会有一条浏览器自己打的红色报错,这是正常的,catch 只能处理 axios 抛出的那一条,界面提示要用 alert 之类的普通用户能看到的方式。

常见错误 ​

  1. 现象:控制台报 axios is not defined,点击按钮毫无反应。 原因:axios 的 <script> 没引入,或写在了业务脚本后面,执行时全局还没有 axios。 修法:CDN 引入放在业务 <script> 之前;改完刷新,先在控制台确认 typeof axios === 'function'。

  2. 现象:res.list 拿到 undefined,页面直接渲染出 “undefined”。 原因:axios 把响应包了一层,服务器数据在 res.data 里,直接取 res.list 取不到。 修法:先 console.log(res) 看结构,再按 res.data.list 逐层取;不确定就先打印再取值。

  3. 现象:配置写了 URL: '...',请求发不出去或地址为空。 原因:axios 配置项全小写,url / method / params / data 都是大小写敏感的。 修法:统一小写,写完对照这四个配置项逐个核对一遍。

  4. 现象:注册接口一直失败,Network 里请求体是空的。 原因:把要提交的数据写进了 params(拼到 URL 上),而不是 data。 修法:查询参数用 params,提交数据用 data,并确认 method: 'post' 已设置。

  5. 现象:手拼 ?pname=湖北省 时漏问号、漏 &,或换省份后查询结果不对。 原因:手动拼字符串容易漏分隔符,中文和特殊字符还需要编码。 修法:一律用 params 对象交给 axios 拼,自己只负责键和值。

  6. 现象:接口报错后控制台一片红,页面上却没有任何提示。 原因:只写了 then,没写 catch,错误被静默丢掉了。 修法:补 .catch(err => ...),提示用户时取 err.response.data.message。

  7. 现象:列表渲染出来是一串带逗号的文本,标签也变成了字符串。 原因:把数组直接赋给 innerText / innerHTML,数组被隐式转成字符串。 修法:map 生成标签字符串数组 → join('') 去掉逗号 → 赋给 innerHTML。

练习 ​

  1. 省份列表渲染:点击按钮请求省份数据,渲染成 <ul><li> 列表,并在列表上方显示“共 N 个省份”。 验收点:Network 里能看到请求;页面无 undefined;省份数量与 res.data.list.length 一致。

  2. 城市查询(带空值保护):一个输入框输入省份名,点击查询用 params 传参并渲染城市列表;输入为空时给出提示且不发请求。 验收点:连续切换两个省份,列表都能正确刷新;空输入时 Network 中没有新请求。

  3. 注册表单:用户名、密码两个输入框 + 提交按钮,POST 提交;成功弹“注册成功”,失败弹后端返回的 message。 验收点:用同一个用户名连续提交两次,第二次能弹出“账号被占用”类提示,而不是控制台报错。

  4. 找 Bug:下面四行配置各有问题,指出并改正。

    js
    axios({ URL: 'http://hmajax.itheima.net/api/register',
            method: 'POST',
            params: { username: 'itheima001', password: '123456' } })
      .then(res => render(res.list))

    验收点:说出至少 3 处问题,并给出修改后的完整代码。

  5. 对比实验:对同一个城市查询,分别用“URL 手拼参数”和“params 对象”各发一次请求,在 Network 面板对比两次请求的 URL,写下你观察到的差异,以及今后你会选哪种写法、为什么。

原视频对照 ​

#视频时长
1AJAX介绍及axios基本使用13:41
2认识URL08:11
3URL查询参数11:58
4案例-省市区查询14:58
5常用请求方法和数据提交08:56
6axios错误处理04:43

小结 ​

  1. 数据来源从本地假数据换成服务器后,事件绑定和 DOM 渲染的写法完全不变,真正变的只有“请求怎么发”和“数据怎么取”。
  2. axios 的 url / method / params / data 四个配置项就能覆盖绝大多数场景,且全部小写。
  3. params 和 data 是两条互不相通的路:写反了请求照样发得出去,但服务器收不到你要的东西。
  4. 响应永远先 res.data,业务字段再往里点;结构不确定时,打印永远比猜快。
  5. then 管成功、catch 管失败;catch 里给用户看的应该是后端返回的 message,不是浏览器的报错文本。
  6. 列表渲染固定三件套:map 生成标签字符串 → join('') 去逗号 → innerHTML 上屏。
  7. 请求地址由后端提供,前端只需认清协议、域名、资源路径三段,并核对参数名和参数值。
  8. 排错顺序:先看 Network 里请求有没有发出、参数对不对,再看响应体,最后才怀疑渲染代码。