前言
在 Web 开发当中,和后端服务器进行交互乃是构建动态网页以及应用程序的关键部分。JavaScript 提供了诸多方式来向后端服务器发送 HTTP 请求,进而获取数据、提交表单或是执行其他操作。
异步数据请求属于构建动态、交互性页面必不可少的一个环节。这一技术准许开发者在无需刷新整个页面的情况下,和服务器交换数据并即时更新页面内容。其中三种主流的异步数据请求方式包括:原生 Ajax、jQuery 库以及 Fetch API。
正文
通过点击页面上的“获取电影列表”按钮,向指定的接口发送出获取信息的请求;将获取到的数据进行解析;最后将获取到的信息在页面上展示出来。
通过这一案例了解原生 Ajax、jQuery 库以及 Fetch API。
原生Ajax
Ajax,全称Asynchronous JavaScript and XML,虽然名字中包含XML,但实际上它可以处理包括JSON在内的多种数据格式。Ajax的核心组件是XMLHttpRequest
对象,它是浏览器提供的一个API,用于创建HTTP请求并与服务器通信。
XMLHttpRequest对象
XMLHttpRequest对象主要的属性:
readyState
:表示请求的状态,有不同的数值表示不同阶段。status
:响应的状态码,如 200 表示成功。responseText
:以文本形式表示的响应数据。responseXML
:如果响应是 XML 数据,可通过这个获取。
XMLHttpRequest对象主要的方法:
open(method, url, async)
:初始化请求,指定请求方法、请求地址和是否异步。send()
:发送请求。setRequestHeader(header, value)
:设置请求头信息。abort()
:终止请求。
XMLHttpRequest对象的readyState属性
其中readyState表示请求的不同阶段,,有 0 到 4 五个值:
- 0: 未初始化,还没有调用open方法。
- 1: 启动,已经调用了open方法,但还没有发送请求。可以调用send方法来发送请求。
- 2: 发送,send 方法已经被调用,且头部和状态已经接收到。可以访问响应的头部信息。
- 3: 接收,响应体正在接收中。响应体数据接收过程中,如果数据是分块传输的,这个状态可能会被多次触发。
- 4: 完成,请求已完成,且响应已经完全接收。请求完成且响应数据完全可用。
XMLHttpRequest对象的status属性
HTTP状态码(status)的主要类别和一些常见的状态码:
-
1xx: 信息响应
-
**100 **:请求的初始部分已接收,客户端应继续发送其余部分。
-
**101 **:服务器同意客户端请求更改协议。
-
-
2xx: 成功
-
**200 **:请求成功并返回所请求的资源。
-
**201 **:请求成功且服务器创建了新资源。
-
**202 **:请求已接受处理,但尚未完成。
-
**204 **:请求成功但没有返回内容。
-
-
3xx: 重定向
-
**301 **:资源已永久移动到新位置。
-
**302 **:资源临时移动到新位置。
-
**304 **:资源未修改,可以使用缓存版本。
-
-
4xx: 客户端错误
-
**400 **:请求无效,服务器无法理解。
-
**401 **:请求未授权,需要身份验证。
-
**403 **:服务器拒绝请求,权限问题。
-
**404 **:请求的资源未找到。
-
**405 **:请求方法不允许。
-
**429 **:客户端发送了过多请求。
-
-
5xx: 服务器错误
- **500 **:服务器内部错误。
- **501 **:服务器不支持请求的方法。
- **502 **:网关或代理服务器收到无效响应。
- **503 **:服务器当前无法处理请求(超载或维护)。
- **504 **:网关或代理服务器超时。
在你发现HTTP状态码是4开头的话就多检查代码,但是如果是5开头的话,你可以理直气壮的找你的后端小伙伴了。
onreadystatechange
onreadystatechange
是 XMLHttpRequest
对象的一个重要事件属性。
当 XMLHttpRequest
对象的 readyState
(请求状态)发生变化时,就会触发该事件。通过为 onreadystatechange
赋值一个函数,可以在请求状态改变的各个阶段执行相应的处理逻辑,比如在请求成功完成(readyState
变为 4 且状态码合适)时获取并处理响应数据等。它是实现对请求过程进行监听和响应处理的关键机制之一。
代码实操
javascript
复制代码
<!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> <button id="btn">获取电影列表</button> <ul id="list"></ul> <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 = () => {//监听请求的过程 if (xhr.readyState == 4 && xhr.status == 200) {//拿到了后端返回的数据 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); } } } }); </script> </body> </html>
- 获取页面中的按钮和无序列表元素。
- 对按钮元素设置一个点击事件监听器,如果点击按钮后:
- 创建一个
XMLHttpRequest
对象实例为xhr
。 - 配置请求方法为 GET,请求地址为指定的接口地址,并设置为异步请求。
- 发送请求。
- 通过
onreadystatechange
监听请求状态的变化,如果变化:- 判断请求状态是否为4(表示请求完成)并且HTTP状态码是否为200(表示成功),如果符合:
- 解析返回的数据为 JSON 格式,并从解析后的结果中获取电影列表。
- 通过循环创建列表项元素,并将电影的名称和星级添加到列表项的文本内容中,最后将列表项添加到无序列表中。
- 判断请求状态是否为4(表示请求完成)并且HTTP状态码是否为200(表示成功),如果符合:
- 创建一个
小结:尽管功能强大,但原生Ajax的代码较为冗长,不易阅读。
效果展示
点击按钮后:
jQuery库
jQuery是一个广泛使用的JavaScript库,它简化了HTML文档遍历、事件处理、动画和Ajax交互等操作。对于Ajax请求,jQuery提供了简洁的API,极大地降低了异步编程的复杂度。
jQuery使用步骤
-
从jquery 网站上复制一个script标签。
-
添加在html文件的head标签里。
$.ajax()方法
$.ajax()
方法是 jQuery 中用于执行异步 HTTP 请求(Ajax 请求)的核心方法。
一些参数:
url
:String 类型,发送请求的地址,默认为当前页地址。method
:String 类型,请求方式,默认为GET
。其他可选值包括POST
、PUT
、DELETE
等,但部分浏览器可能不支持。注意,在远程请求时(不在同一个域下),所有POST
请求都将转为GET
请求。data
:可以是 Object 或 String 类型,发送到服务器的数据。如果是 Object,则必须为 key/value 格式,例如{foo1:"bar1",foo2:"bar2"}
,会自动转换为&foo1=bar1&foo2=bar2
的格式。如果是数组,JQuery 将自动为不同值对应同一个名称,例如{foo:("bar1","bar2")}
会转换为&foo=bar1&foo=bar2
。如果是 String,则会直接附加在 URL 后面。可以通过设置processData
选项来防止这种自动转换。success
:Function 类型,请求成功后调用的回调函数,有两个参数。第一个参数是由服务器返回,并根据dataType
参数进行处理后的数据;第二个参数是描述状态的字符串。error
:Function 类型,请求失败时被调用的函数。该函数有三个参数,即 XMLHttpRequest 对象、错误信息、捕获的错误对象(可选)。
代码实操
html
复制代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <button id="btn">jquery获取电影列表</button> <ul id="list"></ul> <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 (data) { for (let i = 0; i < data.movieList.length; i++) { const li = document.createElement('li') li.innerText = data.movieList[i].nm + '--------' + data.movieList[i].star ul.appendChild(li) } } }) }); </script> </body> </html>
- 复制网站上的script标签。
- 获取按钮和列表元素。
- 为按钮添加点击事件的监听器,当点击按钮:
- 通过
$.ajax()
方法 进行请求配置,包括请求的 URL、方法(GET)、携带的数据(用户名和年龄)。 - 在成功回调函数中,遍历获取到的电影列表数据,为每个电影创建一个列表项并添加到列表中,显示电影名称等信息。
- 通过
小结:使用jQuery的$.ajax
方法,开发者只需几行代码即可完成请求配置,包括请求类型、URL、期望的数据类型以及成功和失败的回调函数。jQuery的链式调用和简化的API设计,使其成为过去许多年中异步请求的首选工具。
效果展示
点击按钮后:
在负载中可以看见发送到服务器的数据信息。
Fetch API
Fetch API是HTML5引入的一个新的、更现代的、基于Promise的网络请求API,旨在替代传统的XMLHttpRequest。Fetch提供了更强大的功能和更灵活的请求控制,同时利用了ES6中的Promise对象,使得异步编程更加优雅。
fetch()函数和.then()方法
fetch()
函数和.then()
方法是现代JavaScript异步编程中的两个关键概念,常用于实现AJAX请求和处理异步操作的结果。
fetch()函数
fetch()
是一个基于Promise的、用于发起网络请求的全局函数,它允许你从服务器检索资源,如JSON数据、文本、图片等。
基本语法:
javascript
复制代码
fetch(url[, options])
url
:必需,一个字符串,表示要获取的资源的URL。options
:可选,一个配置对象,包含请求的额外设置,如HTTP方法、请求头、请求体等。
.then()方法
.then()
方法是Promise对象上的一个方法,用于指定在Promise变为fulfilled(已完成)状态时执行的函数,即当异步操作成功完成时会调用的回调函数。如果有多个.then()
,它们会按照顺序依次执行,每个.then()
都能接收到前一个.then()
中的返回值作为参数。
基本语法:
javascript
复制代码
promise.then(onFulfilled[, onRejected]);
onFulfilled
:当Promise变为fulfilled状态时调用的函数,参数是接收成功的值。onRejected
:可选,当Promise变为rejected状态时调用的函数,参数是Promise的reject原因。
代码实现
javascript
复制代码
<!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> <button id="btn">fetch获取电影列表</button> <ul id="list"></ul> <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')//username="李明"&age=18'是向服务器发送的信息 .then((res) => { // console.log(res);//后端返回的响应体 return res.json() }) .then((data) => { for (let i = 0; i < data.movieList.length; i++) { const li = document.createElement('li') li.innerText = data.movieList[i].nm + '--------' + data.movieList[i].star ul.appendChild(li) } }) }); </script> </body> </html>
- 获取按钮和列表元素。
- 为按钮添加点击事件监听,当按钮被点击:
- 使用
fetch
向指定的 URL 发起请求。 - 通过
then
处理响应,先将响应转换为 JSON 格式。 - 再在另一个
then
中处理转换后的具体数据,创建列表项并添加到列表中。
- 使用
小结:Fetch API使用fetch()
函数发起请求,并通过一系列.then()
处理响应。如果需要,还可以通过.catch()
捕获错误。与jQuery相比,Fetch提供了更原生的异步处理机制,但需要注意的是,Fetch不会自动处理JSON解析,需要手动调用.json()
方法。
效果展示
点击按钮后:
可以通过GET 请求参数向服务器发送信息。
在负载中可以看见发送到服务器的数据信息。
总结
- 原生Ajax提供了最基础的异步通信能力,适合对性能有严格要求或特定场景下的定制化需求。
- jQuery凭借其易用性和跨浏览器兼容性,依然是许多项目中快速实现Ajax请求的优选。
- Fetch API作为新一代标准,以其现代化的Promise支持和更强大的功能,逐渐成为未来趋势,特别是在追求现代JavaScript特性的项目中。
开发者在选择异步请求实现方式时,应考虑项目的具体需求、团队熟悉度及对新特性的追求,从而做出最合适的选择。