前言
什么是Ajax:
Ajax,全称为Asynchronous JavaAScript and XML(异步JavaScript和XML),是一种网页开发技术,它允许在不重新加载整个网页的情况下,通过JavaScript异步地从服务器获取数据并更新部分网页内容。这意味着用户可以与网页进行交互,看到内容的更新,而无需等待整个页面重新加载。
尽管名字中包含XML,现代的Ajax应用实际上可以使用各种格式交换数据,包括JSON(目前最常见), plain text,或者HTML,而不局限于XML。Ajax技术结合了JavaScript、CSS、HTML以及XMLHttpRequest对象(或其他类似的API)来向服务器请求数据,并处理来自服务器的响应。
Ajax的主要优势在于:
- 提升用户体验:页面局部更新,无需整体刷新,使得网页响应更快,用户交互更流畅。
- 减轻服务器负载:因为只传输需要的数据,而非整个页面,减少了带宽使用。
- 实现动态内容更新:如实时聊天、动态加载更多内容、地图应用等交互式功能成为可能。
Ajax是Web 2.0时代的关键技术之一,极大地推动了网页应用向更丰富、更动态的方向发展。
ajax的具体操作流程:
- 创建 XMLHttpRequest 对象: 首先,需要在JavaScript中创建一个XMLHttpRequest对象,这是执行Ajax操作的基础。通常使用
new XMLHttpRequest()来实例化该对象。 - 准备发送请求: 使用XMLHttpRequest对象的
open()方法来初始化一个HTTP请求。这个方法接收三个参数:请求的类型(如 "GET", "POST"),请求的URL,以及一个布尔值表示是否采用异步方式发送请求(true为异步,false为同步,通常使用异步)。 - 设置请求头信息(可选): 如果需要,可以通过
setRequestHeader()方法来设置HTTP请求头,比如Content-Type,这对于发送特定类型的数据(如JSON或表单数据)时可能需要。 - 定义响应处理函数: 设置
onreadystatechange事件处理器,这个事件会在readyState属性值改变时触发。通常会检查readyState是否等于4(表示请求已完成)且status是否为200(表示成功响应)。在这个事件处理函数中处理从服务器接收到的数据。 - 发送请求: 调用XMLHttpRequest对象的
send()方法来发送请求。如果是POST请求,需要将要发送的数据作为参数传递给send()方法;对于GET请求,数据通常附加在URL上,在open()方法中处理。 - 处理服务器响应: 在响应处理函数中,根据需要处理从服务器接收到的数据。这可能涉及到解析JSON、更新DOM、显示错误信息等操作,从而实现页面的局部更新。
总结起来,Ajax操作的核心流程是创建请求对象、配置请求、发送请求、监听响应并处理数据。这一系列操作使得网页能够在后台与服务器交换数据,从而提升用户体验。
readyState
代表ajax的状态,只有状态为4才可以用这份数据
0 --xhr刚创建
1 --open执行
2 --请求发送出去,响应头被接受
3 --响应体正在解析
4 --解析完成
获取电影列表
创建一个获取电影列表的按钮,现在要实现的功能是点击按钮,可以获取到最新的电影列表,通过无序列表展示出来。点击按钮,向后端发送http请求,后端将数据接口传回给前端,通过后端来爬取电影数据,后端接口为:https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get,
<button id="btn">获取电影列表</button>
<ul id="list">
</ul>
这里再给大家讲一下status什么:就是http的状态码
HTTP状态码是用以表示网页服务器HTTP响应状态的3位数字代码,它们按照类别分为五类,每个类别代表了请求处理的不同阶段或结果。下面是这些类别及其常见状态码的概述:
1xx(信息性状态码)
这类状态码表示接收的请求正在处理,需要请求者继续操作。
- 100 Continue:表明到目前为止的请求部分是正确的,客户端应该继续发送剩余的请求。
2xx(成功状态码)
表示请求已经成功被服务器处理。
- 200 OK:请求已成功处理,响应中包含了请求的资源。
- 201 Created:请求成功并且服务器创建了新的资源。
- 202 Accepted:服务器已接受请求,但尚未处理。
3xx(重定向状态码)
需要客户端进一步的操作才能完成请求。
- 301 Moved Permanently:请求的资源已永久移动到新位置。
- 302 Found:请求的资源临时驻留在不同的URI下,将来可能还会更改。
- 304 Not Modified:资源未修改,可以直接使用缓存中的副本。
4xx(客户端错误状态码)
表示客户端的请求中存在错误,服务器无法处理。
- 400 Bad Request:请求无效或无法被服务器理解。
- 401 Unauthorized:请求要求用户的身份认证。
- 403 Forbidden:服务器理解请求客户端的请求,但是拒绝执行此请求。
- 404 Not Found:服务器无法找到请求的资源。
5xx(服务器错误状态码)
表示服务器在处理请求的过程中发生了错误。
- 500 Internal Server Error:服务器遇到了不知道如何处理的情况。
- 502 Bad Gateway:作为网关或代理工作的服务器从上游服务器收到了无效的响应。
- 503 Service Unavailable:服务器目前无法处理请求(由于超载或停机维护)。
思路分析:通过id来获取btn这个按钮元素,并将其命名为btn,为其绑定一个监听事件,当点击该按钮的时候,触发回调函数;在用户点击按钮时,通过Ajax从指定的接口获取电影列表数据,并将这些数据以列表项的形式追加到页面的一个无序列表中,实现了动态加载内容的效果。
<script>
let btn = document.getElementById('btn');
let ul=document.getElementById('list');
btn.addEventListener('click', () => {
//朝一个接口发请求,获取到数据展示到页面上
let xhr = new XMLHttpRequest();//创建一个ajax实例
xhr.open("GET", "https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get", true)//配置发送的参数
xhr.send();//
xhr.onreadystatechange = () => {//监听请求的过程
//console.log(xhr.readyState);
if (xhr.readyState == 4 && xhr.status == 200) {//拿到了后端返回的数据
//console.log(xhr.responseText);
//console.log(JSON.parse(xhr.responseText));转化为对象
//把数据展示到页面上
const movieList = JSON.parse(xhr.responseText).movieList;
console.log(movieList);
for (let i = 0; i < movieList.length; i++) {
const li = document.createElement('li');//创建li元素
li.innerHTML = movieList[i].nm+"-----"+movieList[i].star;//设置li元素的innerHTML
ul.appendChild(li);//把li元素添加到ul元素中
}
}
}
})
</script>
代码分析:
-
获取页面元素:
let btn = document.getElementById('btn');获取id为'btn'的按钮元素。let ul = document.getElementById('list');获取id为'list'的无序列表元素。
-
添加点击事件监听器:
btn.addEventListener('click', ...)为按钮添加点击事件监听器,当按钮被点击时,执行箭头函数内的代码。
-
创建XMLHttpRequest对象:
let xhr = new XMLHttpRequest();创建一个新的XMLHttpRequest对象,用于发送Ajax请求。
-
配置并发送GET请求:
-
xhr.open("GET", "https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get", true);配置请求类型为GET,指定请求的URL,以及设置请求为异步(true)。 -
xhr.send();发送GET请求到指定的URL。
-
- 监听请求状态变化:
xhr.onreadystatechange = () => {...}定义一个函数,当请求状态改变时会被调用。- 判断请求是否完成且状态码为200 (
xhr.readyState == 4 && xhr.status == 200),表示请求成功完成。 - 使用
JSON.parse(xhr.responseText)将服务器响应的文本数据转换为JavaScript对象。
- 判断请求是否完成且状态码为200 (
-
遍历
movieList数组,对于每一个电影对象,执行以下操作: -
创建一个新的
li元素。 -
将电影的名称(
movieList[i].nm)和评分(movieList[i].star)设置为li元素的文本内容。 -
将这个
li元素添加到ul元素中,从而在页面上显示每部电影的信息。最终输出结果如下:
方法二:jQuery
首先要引入jquery库:
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
用Jquery方法可以更加快速的拿到movieList对象,就不用像刚刚那样每次都敲那么多行代码了,更简洁,说白了你可以理解它为一个封装类,就是一个帮你封装好了的东西,你只需要改变里面的后端请求地址就可以了,相比刚刚那个可以节省一些代码量。
<script>
let btn = document.getElementById('btn');
let ul=document.getElementById('list');
btn.addEventListener("click",()=>{
$.ajax({//封装
url:"https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList#!method=get",
method:"GET",
data:{
username:"笑笑",
age:18
},
success:function(res){
console.log(res)}
})
})
</script>
这个方法前两步和上一个是一样的,主要是第三步
发起Ajax请求:
-
使用
$.ajax({...})方法封装了Ajax请求的配置。
url参数指定了请求的目标地址,即电影数据的API接口。method参数指定了请求的方法为"GET"。data参数是一个对象,用于传递额外的数据到服务器,这里示例了传递用户名"笑笑"和年龄18,但实际上这个GET请求并不会在URL中附带这些数据,因为jQuery的data在GET请求中默认不会附加到URL。success参数是一个回调函数,当请求成功时(HTTP状态码为200系列),该函数会被调用,并将服务器响应的数据作为参数res传入。
结果:
可以看到我们同样拿到了这样一个电影数组。最后在success中加上循环数组就可以实现电影列表的输出了。完整代码如下:
<script>
let btn = document.getElementById('btn');
let ul = document.getElementById('list');
btn.addEventListener('click',() => {
$.ajax({
url: 'https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList',
method: 'GET',
data: {
username:'笑笑',
age:18
},
success: function(res) {
const movieList = res.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);
}
}
})
})
</script>
方法三:fetch
在回调函数中,通过fetch("...") 发起一个HTTP GET请求到指定的URL(上面给出后端接口),URL中包含了查询字符串(username='椰汁'&age=18),用于传递参数,在实际应用中可能用于服务器端的某些处理或过滤;
通过.then((res) => {...}) fetch返回一个Promise,当请求成功完成时,第一个.then会被调用,传入的参数res是Response对象,代表了来自服务器的响应;
<script>
let btn = document.getElementById('btn');
let ul=document.getElementById('list');
btn.addEventListener("click",()=>{
fetch("https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList?username='严总'&age=18")
.then((res)=>{
console.log(res);//响应体 没有被解析完全的响应体
return res.json();
})
.then((data)=>{
console.log(data);//响应体 已经被解析成json格式的数据
})
})
</script>
res打印出来的是整个响应体:
用
res.json()将响应体转换成json格式,如下所示:
同样可以实现这个数组的输出。
给后端传递其他参数:
法一: 在后端接口https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList上用?的方式拼接加上一个参数给后端,后端就会解析我们给的参数。例如拼接成https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList?username='笑笑'&age=18。
<script>
let btn = document.getElementById('btn');
let ul = document.getElementById('list');
btn.addEventListener('click', () => { fetch("https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList?username='严总'&age=18")
})
</script>
在电脑的检查网络中的载荷中就可以看到我们传入的参数了
法二:用jquery方法,在其中的$.ajax({}) 里面加上data
<script>
let btn = document.getElementById('btn');
let ul = document.getElementById('list');
btn.addEventListener('click',() => {
$.ajax({
url: 'https://mock.mengxuegu.com/mock/65a91543c4cd67421b34c898/movie/movieList',
method: 'GET',
data: {
username:'严总',
age:18
}
})
})
</script>
三种方法相比较:
1.XMLHttpRequest:经典的实现方式,通过创建请求实例、配置请求参数、发送请求、监听状态变化,直至处理响应数据,步步为营,手动控制请求的全过程。
2.jQuery的$.ajax():简化了操作,提供了一套链式调用接口,让发送请求和处理响应变得直观易懂,尤其适合习惯jQuery框架的开发者。
3.Fetch API:现代浏览器的原生支持,基于Promise设计,代码更为简洁优雅,支持async/await语法,更符合现代JavaScript编程风格。