一、Ajax是什么?
Ajax,全称为Asynchronous JavaScript and XML,即异步的JavaScript和XML,是一种在无需重新加载整个网页的情况下,能够更新部分网页内容的技术。Ajax允许网页与服务器进行异步数据交换,这意味着可以在后台与服务器交换数据,更新部分页面,而用户无需离开当前页面或等待页面完全重载。这大大提高了用户体验,使得网页感觉更快、更动态。
二、Ajax有什么用?
- 提高响应速度和交互性:通过异步数据加载,用户可以在不刷新整个页面的情况下查看新的内容或提交数据,减少了等待时间,使得网页感觉更加流畅和快速。
- 减少服务器负载:由于只需要加载部分内容而非整个页面,服务器传递的数据量减少,处理请求的负担也相应减轻,这对于高流量网站尤其重要。
- 实现页面局部更新:用户界面可以在不干扰用户操作的情况下动态更新,比如实时股价、天气预报更新,或者在线聊天室的即时消息显示。
- 增强应用功能:Ajax使得开发者能够在客户端实现更多复杂功能,如自动完成、动态表单验证、无刷新分页和筛选等,这些都极大地丰富了Web应用的功能性。
- 提升用户体验:减少页面刷新带来的视觉中断和等待时间,使得用户操作连贯,整体感受更加自然和舒适,有助于提高用户满意度和留存率。
三、如何实现Ajax?
html部分,先写一个按钮
<button id="btn">获取电影列表</button>
<ul id="list"></ul>
这段HTML代码定义了一个按钮(ID为"btn")和一个无序列表(ID为"list")。按钮用于触发获取电影列表的操作,无序列表用于展示获取到的电影信息。
分析:
js部分要完成以下功能,以实现ajax:
当点击按钮时,使用Ajax对象以异步的形式向服务器发送一个请求
如果请求被允许(成功),则把获取的数据放入ul标签中,即返回数据,展示在页面上。
有三种方法实现以上功能,有优有劣。
1. 典型的原生JavaScript实现Ajax请求(麻烦)
let btn = document.getElementById('btn');
let ul = document.getElementById('list');
这两行JavaScript代码通过document.getElementById
方法获取页面上的按钮和无序列表元素,并分别存储在变量btn
和ul
中,以便后续操作使用。
btn.addEventListener('click', () => {})
这一行代码为按钮添加了一个点击事件监听器。当按钮被点击时,会执行大括号内的匿名函数。
let xhr = new XMLHttpRequest();
这行代码创建了一个新的XMLHttpRequest对象,这是执行Ajax请求的关键对象,专门为实现ajax而设置的对象。
xhr.open('GET', 'https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get', true);
xhr.send();
通过xhr.open
方法配置了一个HTTP GET请求,指定了请求的URL和设置为异步请求(最后一个参数为true
)。随后,xhr.send()
方法发送了这个请求到服务器。
xhr.onreadystatechange = () => {
if(xhr.readyState == 4 && xhr.status == 200) {
}
}
这里为xhr
对象设置了onreadystatechange
事件处理器,当请求的状态改变时会执行。xhr.readyState == 4
表示请求已完成,xhr.status == 200
表示请求成功,两者条件都满足时进入if语句块。
console.log(JSON.parse(xhr.responseText));
这行代码读取了服务器响应的文本内容(xhr.responseText
),使用JSON.parse
将其转换为JavaScript对象,并打印到控制台以便调试。(检查自己是否成功获取到数据)
const movieList = JSON.parse(xhr.responseText).movieList;
for(let i = 0; i < movieList.length; i++){
const li = document.createElement('li');
li.innerText = movieList[i].nm + '--' + movieList[i].star;
ul.appendChild(li);
}
这部分代码处理了成功的响应数据。首先,再次将响应内容解析为JSON对象,并从中提取出movieList
数组。然后,使用for循环遍历这个数组,对每个电影项目创建一个新的<li>
元素,将电影的名称(.nm
)和主演(.star
)信息设置为这个<li>
元素的文本内容,最后将这个元素添加到页面上的无序列表(ul
)中,实现动态展示电影列表的功能。
总结起来,这段代码实现了以下逻辑:
- 点击按钮触发Ajax请求。
- 向指定URL发送GET请求以获取电影列表数据。
- 监听请求状态,一旦请求成功完成,处理返回的JSON数据。
- 将处理后的电影数据动态添加到页面的无序列表中,呈现给用户。
整体代码:
// 获取页面上的按钮和列表元素
let btn = document.getElementById('btn');
let ul = document.getElementById('list');
// 为按钮添加点击事件监听器
btn.addEventListener('click', function() {
// 创建一个XMLHttpRequest对象,这是进行Ajax通信的核心组件
let xhr = new XMLHttpRequest();
// 配置请求: 使用GET方法,请求的目标URL以及设置请求为异步模式
xhr.open('GET', 'https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get', true);
// 发送请求到服务器
xhr.send();
// 设置一个事件处理器来监听请求的状态变化
xhr.onreadystatechange = function() {
// 当请求完成(状态4)且响应状态为200(成功)时,执行以下代码
if(xhr.readyState === 4 && xhr.status === 200) {
// 解析从服务器返回的JSON格式数据
let movieData = JSON.parse(xhr.responseText);
// 从解析的数据中提取电影列表
const movieList = movieData.movieList;
// 清空列表以准备展示新数据(如果需要的话)
ul.innerHTML = '';
// 遍历电影列表
for(let i = 0; i < movieList.length; i++) {
// 为每部电影创建一个新的列表项(li元素)
let listItem = document.createElement('li');
// 设置列表项的内容为电影名和主演
listItem.textContent = movieList[i].nm + '--' + movieList[i].star;
// 将列表项添加到无序列表中
ul.appendChild(listItem);
}
}
};
});
补充:
有些人可能对if(xhr.readyState === 4 && xhr.status === 200)
不了解,为什么这样就判定成功了,这里做一下补充:
-
xhr.readyState === 4: 这个条件检查请求的状态是否为4,
readyState
属性表示请求/响应过程的不同阶段。它共有5个可能的值:- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中(通常响应中已有部分数据可访问,但尚未完成)
- 4: 请求已完成且响应已就绪
当
readyState
变为4,意味着整个请求已经完成,响应数据已经可以使用。 -
xhr.status === 200: 这个条件检查HTTP响应状态码是否为200。HTTP状态码是用来表示网页服务器超文本传输协议响应状态的3位数字代码。200状态码表示请求已成功处理,一切正常。常见的其他状态码还包括404(未找到)、500(服务器内部错误)等。
结合在一起,if(xhr.readyState === 4 && xhr.status === 200)
就是在确认请求已经结束并且服务器返回了一个成功的响应。只有在这两个条件都满足时,才会执行紧跟其后的代码块,通常是在这里处理响应数据,比如解析JSON、更新DOM等。这是确保我们只在获得有效响应时才进行后续操作,避免处理不完整或错误的响应数据
2.使用jQuery库来实现Ajax请求(不是最优)
核心代码 Javascript
$.ajax({
url: 'https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get',
method: 'GET',
data: {
username: '坤坤',
age: 18
},
success: function(res) {
console.log(res);
}
});
使用jQuery的$.ajax
方法发送一个Ajax请求:
url
: 指定请求的URL,这里是模拟接口,用于获取电影列表。method
: 请求的方法,这里是GET。data
: 请求携带的数据,尽管在这个GET请求中传递这些数据可能不会以查询字符串形式附加到URL上(取决于服务器配置和jQuery的具体行为),通常GET请求的查询参数会直接拼接在URL上,但这里作为示例展示了如何传递额外数据。success
: 请求成功后的回调函数,res
参数是服务器返回的数据。在这个示例中,只是简单地将响应数据打印到控制台。
jQuery$.ajax
方法已经帮你实现了核心逻辑,你只需要在相应位置上填上相应的数据就可以。
整体代码:
// 获取按钮和列表元素
let btn = document.getElementById('btn');
let ul = document.getElementById('list');
// 为按钮添加点击事件监听器
btn.addEventListener('click', function() {
// 使用jQuery的$.ajax方法发起一个GET类型的Ajax请求
$.ajax({
// 设置请求的URL
url: 'https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get',
// 请求的方法为GET
method: 'GET',
// 请求携带的数据,尽管在GET请求中这些数据通常不会以这种方式发送(通常应为查询参数)
data: {
username: '笑笑', // 示例用户名
age: 18 // 示例年龄
},
// 请求成功后的回调函数
success: function(res) {
// 打印服务器响应的数据到控制台
console.log(res);
// 下面是示例代码,用于将获取到的电影列表数据渲染到页面上
// 假设res是包含电影列表的对象,其中movieList是电影数组
/*
const movieList = res.movieList;
movieList.forEach(movie => {
let li = document.createElement('li');
li.textContent = `${movie.name} - ${movie.director}`;
ul.appendChild(li);
});
*/
}
});
});
对于那些已经在使用jQuery库的项目,因为它提供了简洁、链式操作的API,使得Ajax请求的编写变得简单直观。然而,随着时间的推移和Web技术的发展,一些新的趋势和替代方案逐渐受到青睐,这主要是出于以下几个原因:
- 体积与性能:jQuery是一个大型库,包含了许多功能,而不仅仅是Ajax。对于只需Ajax功能的现代项目,引入整个jQuery可能会导致页面加载时间增加和资源占用过多。相比之下,使用原生的
XMLHttpRequest
或者更现代的fetch
API可以实现更轻量级的解决方案。 - 现代浏览器的支持:随着现代浏览器对ES6及更高版本特性的全面支持,原生的JavaScript功能已经足够强大,可以直接使用
fetch
API来处理Ajax请求,它提供了更符合现代JavaScript编程习惯的Promise API,使得异步编程更加简洁和易于管理。 - 模块化和框架的发展:随着前端工程化的推进,像React、Vue、Angular这样的现代前端框架成为主流,它们通常推荐使用自己的数据管理方式(如React的Hooks、Vue的axios等)或者提倡使用更小、更专注于单一职责的库来处理网络请求,以适应模块化和组件化的开发模式。
- 社区和趋势:随着前端技术栈的快速迭代,开发者社区对新技术的探索和采纳,新的工具和实践不断涌现,像Axios这样的独立库因其灵活性和易用性受到了广泛的欢迎,它们提供了丰富的特性集,比如拦截请求、自动转换请求和响应数据等,而不需要引入整个jQuery库。
综上所述,虽然使用jQuery的$.ajax
依然是可行的选项,特别是在维护旧项目或者团队对此有深厚积累的情况下,但从长远看,考虑到性能优化、代码的现代性和生态的多样性,更多的项目倾向于采用原生API或现代库来处理Ajax请求。这就是我们接下来要说的第三种实现Ajax的方法。
3. 使用Fetch API来实现Ajax请求(经常用且最优)
核心代码:
btn.addEventListener('click', () => {
fetch("https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get?username='曾总'&age=18") // ? username = '曾总'&age=18
.then((res) => {
return res.json()
})
.then((data) => {
console.log(data);
})
})
首先,通过getElementById
方法获取页面中ID为"btn"的按钮元素和ID为"list"的无序列表元素。
btn.addEventListener('click', () => {
// ...
});
为按钮添加一个点击事件监听器,当按钮被点击时,执行里面的箭头函数。
fetch("https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get?username='曾总'&age=18")
使用Fetch API发送一个GET请求到指定的URL。这里直接在URL后面添加查询参数(username='曾总'&age=18
),这是传递请求参数的一种方式,但需要注意,由于URL中特殊字符需要编码,实际上正确的传递方式应该是对参数进行URL编码,例如username=%E6%9B%BE%E6%80%BB&age=18
。不过,对于演示目的,这里的写法能直观理解参数传递的概念。
.then((res) => {
return res.json();
})
fetch
返回一个Promise,当请求成功时,第一个.then
被调用。这里接收到了响应对象res
,然后调用res.json()
将响应体转换为JSON格式的Promise。这个转换是必要的,因为原始响应体可能不是JSON格式,而是Blob、FormData等。
.then((data) => {
console.log(data);
})
上一步转换成JSON之后的Promise链继续用.then
处理,这里接收到了转换后的JSON数据,并将其打印到控制台。
注意:为了完整实现需求,可能还需要进一步处理data
,比如遍历电影列表并将其添加到页面上,这部分逻辑可以根据实际需求添加到第二个.then
的处理函数中。
四、结语
在现代Web开发领域,Ajax技术无疑扮演着至关重要的角色,它不仅极大地丰富了用户体验,还推动了Web应用向着更高效、更互动的方向发展。通过上述探讨,我们不仅回顾了Ajax的基本概念及其带来的显著优势,还深入学习了三种实现Ajax请求的方法:原生JavaScript、jQuery的$.ajax
方法,以及现代Web开发中越来越受欢迎的Fetch API。
- 原生JavaScript提供了最基础、最灵活的实现方式,适合于任何JavaScript环境,但代码相对繁琐。
- jQuery的$.ajax简化了Ajax操作,凭借其链式调用和广泛的支持,成为过去很长一段时间内的首选,尽管在现代轻量化和性能优先的趋势下,它的使用有所减少。
- Fetch API作为现代Web标准的一部分,以其原生支持、基于Promise的异步处理机制和更简洁的语法,成为了目前实现Ajax请求的优选方案,特别适合追求代码质量与性能的现代项目。
选择合适的Ajax实现方式,依据项目需求、团队熟悉度及技术栈的兼容性来决定。无论是维护遗留系统、快速构建原型,还是开发高性能、现代化的Web应用,深刻理解Ajax的核心原理与不同实现手段,都将使你能够更加灵活地应对各种交互需求,从而在Web开发领域游刃有余。拥抱Ajax,开启你的动态Web交互之旅,让用户的每一次点击都充满惊喜与流畅。