1.1 XMLHttpRequest - 基础使用
目标
- 了解 AJAX 原理和
XMLHttpRequest
的基础使用。
讲解
1. AJAX 原理
- AJAX 是浏览器与服务器通信的技术,基于
XMLHttpRequest
对象。 axios
是对XHR
的封装,简化了接口参数传递。- 学习
XHR
可帮助理解axios
内部与服务器交互的原理。
2. 基础语法
javascript
const xhr = new XMLHttpRequest(); | |
xhr.open('请求方法', '请求url网址'); | |
xhr.addEventListener('loadend', () => { | |
console.log(xhr.response); | |
}); | |
xhr.send(); |
3. 示例代码
html
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>XMLHttpRequest_基础使用</title> | |
</head> | |
<body> | |
<p class="my-p"></p> | |
<script> | |
const xhr = new XMLHttpRequest(); | |
xhr.open('GET', 'http://hmajax.itheima.net/api/province'); | |
xhr.addEventListener('loadend', () => { | |
const data = JSON.parse(xhr.response); | |
document.querySelector('.my-p').innerHTML = data.list.join('<br>'); | |
}); | |
xhr.send(); | |
</script> | |
</body> | |
</html> |
小结
- AJAX 原理:基于
window
提供的XMLHttpRequest
对象。 - 学习 XHR 的原因:掌握更多与服务器通信的方式,了解
axios
内部原理。 - XHR 使用步骤:
- 创建
XHR
对象。 - 调用
open
方法,设置 URL 和请求方法。 - 监听
loadend
事件,接收结果。 - 调用
send
方法,发起请求。
- 创建
1.2 XMLHttpRequest - 查询参数
目标
- 使用
XHR
传递查询参数给服务器,获取匹配数据。
讲解
1. 什么是查询参数
- 携带额外信息给服务器,返回匹配的数据。
- 语法:
http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2
。 - 原生
XHR
需手动拼接查询参数字符串。
2. 示例代码
javascript
const xhr = new XMLHttpRequest(); | |
xhr.open('GET', 'http://hmajax.itheima.net/api/city?pname=辽宁省'); | |
xhr.addEventListener('loadend', () => { | |
const data = JSON.parse(xhr.response); | |
document.querySelector('.city-p').innerHTML = data.list.join('<br>'); | |
}); | |
xhr.send(); |
小结
- 携带查询参数:在
open
方法的 URL 后拼接参数名和值。
1.3 案例 - 地区查询
目标
- 使用
XHR
完成地区查询案例。
讲解
1. 需求
- 输入省份和城市名字,点击查询,传递多对查询参数并获取地区列表。
2. 使用 URLSearchParams
javascript
const paramsObj = new URLSearchParams({ | |
参数名1: 值1, | |
参数名2: 值2 | |
}); | |
const queryString = paramsObj.toString(); | |
// 结果:参数名1=值1&参数名2=值2 |
小结
- JS 对象转查询参数:使用
URLSearchParams
对象。
1.4 XMLHttpRequest - 数据提交
目标
- 通过
XHR
提交用户名和密码,完成注册功能。
讲解
1. 需求
- 使用
XHR
提交用户注册信息。
2. 步骤
- 设置请求头
Content-Type: application/json
。 - 将 JS 对象转为 JSON 字符串。
- 在
send
方法中携带请求体数据。
3. 示例代码
javascript
document.querySelector('.reg-btn').addEventListener('click', () => { | |
const xhr = new XMLHttpRequest(); | |
xhr.open('POST', 'http://hmajax.itheima.net/api/register'); | |
xhr.addEventListener('loadend', () => { | |
console.log(xhr.response); | |
}); | |
xhr.setRequestHeader('Content-Type', 'application/json'); | |
const userObj = { username: 'itheima007', password: '7654321' }; | |
const userStr = JSON.stringify(userObj); | |
xhr.send(userStr); | |
}); |
小结
- 提交请求体数据:在
send
中携带请求体数据,并设置Content-Type
。
1.5 认识 Promise
目标
- 认识
Promise
的作用、好处及使用步骤。
讲解
1. 什么是 Promise
- 表示一个异步操作的最终完成(或失败)及其结果值。
2. Promise
的好处
- 逻辑更清晰(成功或失败关联后续处理函数)。
- 解决回调函数地狱问题。
3. 基础语法
javascript
const p = new Promise((resolve, reject) => { | |
// 执行异步任务 | |
// 成功调用 resolve(值),失败调用 reject(值) | |
}); | |
p.then(result => { | |
// 成功 | |
}).catch(error => { | |
// 失败 | |
}); |
4. 示例代码
javascript
const p = new Promise((resolve, reject) => { | |
setTimeout(() => { | |
reject(new Error('模拟AJAX请求-失败结果')); | |
}, 2000); | |
}); | |
p.then(result => { | |
console.log(result); | |
}).catch(error => { | |
console.log(error); | |
}); |
小结
Promise
是什么:表示一个异步操作最终状态和结果值的对象。- 学习
Promise
的原因:了解axios
内部运作原理。 - 使用步骤:
- 创建
Promise
对象,执行异步任务。 - 用
resolve
关联then
的回调函数。 - 用
reject
关联catch
的回调函数。
- 创建
1.6 认识 Promise 的状态
目标
- 认识
Promise
的三种状态及其作用。
讲解
1. 三种状态
- 待定(pending):初始状态。
- 已兑现(fulfilled):操作成功完成。
- 已拒绝(rejected):操作失败。
2. 状态的作用
- 状态改变后,触发对应的回调函数。
- 状态一旦敲定,无法再改变。
小结
- 三种状态:
pending
、fulfilled
、rejected
。 - 状态的作用:关联处理函数,决定代码执行顺序。
1.7 使用 Promise 和 XHR 获取省份列表
目标
- 用
Promise
管理XHR
异步任务。
讲解
1. 需求
- 使用
Promise
和XHR
请求省份列表数据并展示到页面。
2. 示例代码
javascript
const p = new Promise((resolve, reject) => { | |
const xhr = new XMLHttpRequest(); | |
xhr.open('GET', 'http://hmajax.itheima.net/api/province'); | |
xhr.addEventListener('loadend', () => { | |
if (xhr.status >= 200 && xhr.status < 300) { | |
resolve(JSON.parse(xhr.response)); | |
} else { | |
reject(new Error(xhr.response)); | |
} | |
}); | |
xhr.send(); | |
}); | |
p.then(result => { | |
document.querySelector('.my-p').innerHTML = result.list.join('<br>'); | |
}).catch(error => { | |
console.dir(error); | |
document.querySelector('.my-p').innerHTML = error.message; | |
}); |
小结
- 判断请求成功:响应状态码在
200
到300
之间。
1.8 封装简易 axios - 获取省份列表
目标
- 模拟
axios
函数封装,了解其内部运作原理。
讲解
1. 需求
- 基于
Promise
和XHR
封装myAxios
函数,获取省份列表。
2. 核心语法
javascript
function myAxios(config) { | |
return new Promise((resolve, reject) => { | |
const xhr = new XMLHttpRequest(); | |
xhr.open(config.method || 'GET', config.url); | |
xhr.addEventListener('loadend', () => { | |
if (xhr.status >= 200 && xhr.status < 300) { | |
resolve(JSON.parse(xhr.response)); | |
} else { | |
reject(new Error(xhr.response)); | |
} | |
}); | |
xhr.send(); | |
}); | |
} | |
myAxios({ | |
url: 'http://hmajax.itheima.net/api/province' | |
}).then(result => { | |
console.log(result); | |
}).catch(error => { | |
console.log(error); | |
}); |
小结
- 设置默认请求方法:
config.method
判断有值就用,无值用GET
。
1.9 封装简易 axios - 获取地区列表
目标
- 修改
myAxios
函数支持传递查询参数,获取地区列表。
讲解
1. 需求
- 支持传递查询参数,获取辽宁省、大连市的地区列表。
2. 示例代码
javascript
function myAxios(config) { | |
return new Promise((resolve, reject) => { | |
const xhr = new XMLHttpRequest(); | |
if (config.params) { | |
const paramsObj = new URLSearchParams(config.params); | |
const queryString = paramsObj.toString(); | |
config.url += `?${queryString}`; | |
} | |
xhr.open(config.method || 'GET', config.url); | |
xhr.addEventListener('loadend', () => { | |
if (xhr.status >= 200 && xhr.status < 300) { | |
resolve(JSON.parse(xhr.response)); | |
} else { | |
reject(new Error(xhr.response)); | |
} | |
}); | |
xhr.send(); | |
}); | |
} | |
myAxios({ | |
url: 'http://hmajax.itheima.net/api/area', | |
params: { | |
pname: '辽宁省', | |
cname: '大连市' | |
} | |
}).then(result => { | |
console.log(result); | |
}); |
小结
- 查询参数转换:使用
URLSearchParams
对象。
1.10 封装简易 axios - 注册用户
目标
- 修改
myAxios
函数支持传递请求体数据,完成注册用户。
讲解
1. 需求
- 支持传递请求体数据,完成注册用户功能。
2. 示例代码
javascript
function myAxios(config) { | |
return new Promise((resolve, reject) => { | |
const xhr = new XMLHttpRequest(); | |
if (config.params) { | |
const paramsObj = new URLSearchParams(config.params); | |
const queryString = paramsObj.toString(); | |
config.url += `?${queryString}`; | |
} | |
xhr.open(config.method || 'GET', config.url); | |
xhr.addEventListener('loadend', () => { | |
if (xhr.status >= 200 && xhr.status < 300) { | |
resolve(JSON.parse(xhr.response)); | |
} else { | |
reject(new Error(xhr.response)); | |
} | |
}); | |
if (config.data) { | |
const jsonStr = JSON.stringify(config.data); | |
xhr.setRequestHeader('Content-Type', 'application/json'); | |
xhr.send(jsonStr); | |
} else { | |
xhr.send(); | |
} | |
}); | |
} | |
document.querySelector('.reg-btn').addEventListener('click', () => { | |
myAxios({ | |
url: 'http://hmajax.itheima.net/api/register', | |
method: 'POST', | |
data: { | |
username: 'itheima999', | |
password: '666666' | |
} | |
}).then(result => { | |
console.log(result); | |
}).catch(error => { | |
console.dir(error); | |
}); | |
}); |
小结
- 携带请求体参数:判断
data
选项,转成 JSON 字符串并设置请求头。
1.11 案例 - 天气预报 - 默认数据
目标
- 将北京市的数据填充到页面默认显示。
讲解
1. 需求
- 获取北京市天气预报并展示。
2. 示例代码
javascript
function getWeather(cityCode) { | |
myAxios({ | |
url: 'http://hmajax.itheima.net/api/weather', | |
params: { | |
city: cityCode | |
} | |
}).then(result => { | |
const wObj = result.data; | |
document.querySelector('.title').innerHTML = ` | |
<span class="dateShort">${wObj.date}</span> | |
<span class="calendar">农历 | |
<span class="dateLunar">${wObj.dateLunar}</span> | |
</span> | |
`; | |
document.querySelector('.area').innerHTML = wObj.area; | |
document.querySelector('.weather-box').innerHTML = ` | |
<div class="tem-box"> | |
<span class="temp"> | |
<span class="temperature">${wObj.temperature}</span> | |
<span>°</span> | |
</span> | |
</div> | |
<div class="climate-box"> | |
<div class="air"> | |
<span class="psPm25">${wObj.psPm25}</span> | |
<span class="psPm25Level">${wObj.psPm25Level}</span> | |
</div> | |
<ul class="weather-list"> | |
<li> | |
<img src="${wObj.weatherImg}" class="weatherImg" alt=""> | |
<span class="weather">${wObj.weather}</span> | |
</li> | |
<li class="windDirection">${wObj.windDirection}</li> | |
<li class="windPower">${wObj.windPower}</li> | |
</ul> | |
</div> | |
`; | |
}); | |
} | |
getWeather('110100'); |
小结
- 收获:完成一个有意义的业务,测试
myAxios
函数。
1.12 案例 - 天气预报 - 搜索城市列表
目标
- 根据关键字展示匹配的城市列表。
讲解
1. 需求
- 输入关键字,展示匹配的城市列表。
2. 示例代码
javascript
document.querySelector('.search-city').addEventListener('input', (e) => { | |
myAxios({ | |
url: 'http://hmajax.itheima.net/api/weather/city', | |
params: { | |
city: e.target.value | |
} | |
}).then(result => { | |
const liStr = result.data.map(item => { | |
return `<li class="city-item" data-code="${item.code}">${item.name}</li>`; | |
}).join(''); | |
document.querySelector('.search-list').innerHTML = liStr; | |
}); | |
}); |
小结
- 监听输入框事件:
input
事件。
1.13 案例 - 天气预报 - 展示城市天气
目标
- 点击搜索框列表城市名字,切换对应城市天气数据。
讲解
1. 需求
- 点击城市列表名字,切换当前页面天气数据。
2. 示例代码
javascript
document.querySelector('.search-list').addEventListener('click', e => { | |
if (e.target.classList.contains('city-item')) { | |
const cityCode = e.target.dataset.code; | |
getWeather(cityCode); | |
} | |
}); |
小结
- 传递参数:根据后端要求传递城市名字或
code
值。