入门AJAX——XMLHttpRequest(Get) - 教程

news/2025/10/5 12:38:39/文章来源:https://www.cnblogs.com/ljbguanli/p/19126473

入门AJAX——XMLHttpRequest(Get) - 教程

一、什么是 AJAX

AJAX = Asynchronous JavaScript And XML(异步的 JavaScript 和 XML)。

1、XML与异步JS

XML: 是一种比较老的前后端数据传输格式(已经几乎被 JSON 代替)。它的格式与HTML类似,通过严格的闭合自定义标签实现对数据的解释。

异步JS: 所谓异步与同步相对。同步指的是当JS遇到耗时操作(网络请求)时原地等待操作完成而阻塞下面的代码。而异步JS在遇到耗时操作时会继续执行下面的代码,等响应返回后继续处理。

2、AJAX的特点

AJAX最大的优点就是可以在不重新加载这个页面的情况下,与服务器交换部分数据并且更新部分网页内容。

3、本文我们会做什么

实现AJAX的方法可以大概分为两种:XMLHttpRequestfetch ,在本文,我们着重介绍前者。

既然是网络请求,就自然需要后端的支持。我们会首先搭建一个本地的后端服务器。前端小伙伴看到这可能不淡定了:

什么?让我去写后端,还是算了,告辞!

先别急着走嘛,当然啦,我这边已经把接口部署到服务器上了,大家如果嫌麻烦的话,下文中的所有 url 前缀请使用 http://39.105.227.198:1234并跳过下文中的后端接口搭建内容。

完整代码在文章末尾(前端,使用在线接口)

4、前置知识

学习本文之前,请确保你已经了解了下面知识点的相关概念和基础用法:

二、实现简单的 AJAX

1、基于express快速搭建后端接口

后端搭建不是本文重点,所以直接上代码,如果你使用的是服务器上的接口,可以跳过本节:

npm install express body-parser cookie-parser multer cors --save

根目录下新建 app.js

const express = require('express'
)
const cors = require('cors'
)
const app = express(
)
app.use(cors(
)
)
app.get('/test/1'
, (req, res
) =>
{
res.send('hello world'
)
}
)
app.listen(1234
, (
) =>
{
console.log('服务器运行在 http://localhost:1234'
)
}
)

启动本服务器,我们将与 1234 端口交互:

node ./app.js
服务器运行在 http://localhost:1234

看到服务器运行在 http://localhost:1234标标标明服务器启动成功。

2、前端请求

下面我们通过代码来认识如何去使用 XMLHttpRequest发起AJAX请求:

// html 文件
<div id="app"></div>
<script>// 创建请求对象const xhr =new XMLHttpRequest()// 如果你使用的是我提供的服务器接口,请将 url 修改为:// http://39.105.227.198:1234/test/1const url = 'http://localhost:1234/test/1'// 配置:向 url 发起异步 GET 请求xhr.open('GET', url, true)xhr.onreadystatechange =function () {// 如果请求成功if (xhr.readyState === 4 && xhr.status === 200) {const res = xhr.responseText// 将 ID 为 app 的元素内文字改为响应的文字document.querySelector('#app').innerHTML = res}}// 发送请求xhr.send()
</script>

运行上面的 html 代码,你将在页面上看到后端返回的 hello world!,并在调试台看到网页发送了一次 GET 请求。

在这里插入图片描述
恭喜你,已经成功发出了一个 AJAX 请求并收到返回的结果!

3、知识点讲解

现在回看我们的代码都干了什么:

首先我们创建了一个请求对象 xhr :

const xhr =
new XMLHttpRequest(
)

接下来我们对 AJAX 请求的控制本质上就是对这个 xhr 的控制。

然后我们对本次发送的请求进行配置:

// 如果你使用的是我提供的服务器接口,请将 url 修改为:
// http://39.105.227.198:1234/test/1
const url = 'http://39.105.227.198:1234/test/1'
// 配置:向 url 发起异步 GET 请求
xhr.open('GET'
, url, true
)

xhr.open()方法接收三个参数:method、url 和 isAsync

  • method: 本次请求的方法,如 get、post等。
  • url: 顾名思义,本次请求要发到哪里。
  • isAsync: 自己起的名字,本次请求是否异步,我们建议使用异步。

在 xhr 对象上有一个属性 readyState,该属性的取值范围是0~4,用于跟踪请求的进度并处理响应。

状态码常量描述
0UNSENTXHR 对象已创建,但尚未调用 open() 方法。
1OPENED已调用 open() 方法,请求已初始化,但尚未发送(未调用 send())。
2HEADERS_RECEIVED已调用 send() 方法,服务器已接收请求并返回响应头。
3LOADING服务器正在返回响应体(数据正在传输中),responseText 已有部分数据。
4DONE请求已完成(成功或失败),响应数据已完全接收。

onreadystatechange 是一个事件处理函数,当 XHR 的 readyState 状态发生变化时会触发该事件。开发者可以通过监听这个事件来跟踪请求的进度并处理响应。

xhr.onreadystatechange =
function (
) {
// 如果请求成功
// status 是状态码,200 ~ 299 表示请求成功
if (xhr.readyState === 4 && xhr.status === 200
) {
const res = xhr.responseText
// 将 ID 为 app 的元素内文字改为响应的文字
document.querySelector('#app'
).innerHTML = res
}
}

所以上面代码的意思就是:当请求完成并且成功返回后,将 id 为 app 的元素内文字改为响应的结果(hello world)。然后我们使用 xhr.send()发送请求。

三、实现一个简单的搜索词推荐功能

让我们实现一个简单的搜索词推荐功能:页面上有一个输入框,只能接收一个小写英文字母,每次我们输入,都会主动向服务器发送当前输入框内的字母,然后服务器返回一个以这个字母开头的单词,前端将这个单词显示在页面上,如果没有匹配到任何一个单词,则返回 no suggest。

1、后端代码

如果你依旧使用我提供的接口,那么该节内容你依旧不需要阅读,记得请求时把 URL 改正确就行。

我们的代码基于之前的代码:

// app.js
const express = require('express'
)
const cors = require('cors'
)
const app = express(
)
app.use(cors(
)
)
app.get('/test/1'
, (req, res
) =>
{
res.send('hello world'
)
}
)
/* --------------添加代码-----------------*/
app.get('/test/2'
, (req, res
) =>
{
const char = req.query.char
res.send(char2Word.get(char) || 'no suggest'
)
}
)
const char2Word =
new Map(
)
char2Word.set('a'
, 'Anna'
)
char2Word.set('b'
, 'Brittany'
)
char2Word.set('c'
, 'Cinderella'
)
char2Word.set('d'
, 'Diana'
)
char2Word.set('e'
, 'Eva'
)
char2Word.set('f'
, 'Fiona'
)
char2Word.set('g'
, 'Gunda'
)
char2Word.set('h'
, 'Hege'
)
char2Word.set('i'
, 'Inga'
)
char2Word.set('j'
, 'Johanna'
)
char2Word.set('k'
, 'Kitty'
)
char2Word.set('l'
, 'Linda'
)
char2Word.set('m'
, 'Mom'
)
char2Word.set('n'
, 'No'
)
char2Word.set('o'
, 'Ok'
)
char2Word.set('p'
, 'Picture'
)
char2Word.set('q'
, 'Quick'
)
char2Word.set('r'
, 'Reset'
)
char2Word.set('s'
, 'String'
)
char2Word.set('t'
, 'TypeSrcipt'
)
char2Word.set('u'
, 'unit'
)
char2Word.set('v'
, 'Vicky'
)
char2Word.set('w'
, 'Wenche'
)
char2Word.set('x'
, 'x-rian'
)
char2Word.set('y'
, 'Yellow'
)
char2Word.set('z'
, 'Zoom'
)
/* --------------添加代码-----------------*/
app.listen(1234
, (
) =>
{
console.log('服务器运行在 http://localhost:1234'
)
}
)

2、前端代码

创建一个输入框和一个用于显示搜索结果的盒子:

<input id="charInput" placeholder="请输入一个小写字母" type="text">
<div id="suggest">no suggest</div>

接下来,我们将请求进行简单的封装,以后我们想发起请求只需调用该函数:

function getRequest (url, callback
) {
const xhr =
new XMLHttpRequest(
)
xhr.open('GET'
, url, true
)
xhr.onreadystatechange =
function (
) {
if (xhr.readyState === 4 && xhr.status === 200
) {
const res = xhr.responseText
callback(res)
}
}
xhr.send(
)
}

然后给 input 输入框绑定输出事件回调,每次输入就调用getRequest将出入的字母发送到后端,获取到结果后将其设置到下面的 div 中:

inputChange = (str
) =>
{
// 如果你使用的是我提供的服务器接口,请将 url 修改为:
// http://39.105.227.198:1234/test/2?char=${str}
getRequest(`http://localhost:1234/test/2?char=${str
}`
, (res
) =>
{
document.querySelector('#suggest'
).innerHTML = res
}
)
}
document.querySelector('#charInput'
)
.addEventListener('input'
, (e
) =>
inputChange(e.target.value)
)

至此前端代码书写完毕,运行 html ,在输入框中输入一个小写字母,发现下面的建议文字会跟着变化,且建议文字的首字母就是你输入的字母:

在这里插入图片描述

四、请求的超时取消

很多时候我们希望当请求长时间没有响应时取消该请求,在XMLHttpRequest中,我们使用 abort()函数实现。

const xhr =
new XMLHttpRequest(
)
// ... 代码
xhr.abort(
) // 取消请求

我们现在对上文中的 getRequest 函数进行以下扩展,使它支持超时取消:

// 添加超时事件和取消回调
function getRequest (url, callback, timeout = 5000
, abortCallBack = (
) =>
{
}
) {
const xhr =
new XMLHttpRequest(
)
setTimeout((
) =>
{
xhr.abort(
)
abortCallBack(
)
}
, timeout)
xhr.open('GET'
, url, true
)
xhr.onreadystatechange =
function (
) {
if (xhr.readyState === 4 && xhr.status === 200
) {
const res = xhr.responseText
callback(res)
}
}
xhr.send(
)
}

我们新建一个接口,让这个接口延迟3秒后返回结果。

然后布置两个盒子,其中一个设置为1秒超时,一个设置为5秒超时。

如果成功接收到接口的返回值,就将盒子的内容更改为该返回值,被取消请求的盒子内容改为:“我的请求被取消”。

让我们先预测一下,应该是第一个盒子的内容应该是“我的内容被取消”,因为它设置到超时时间短于结果的返回所需时间;而第二个盒子的内容可以被正常修改:

// app.js
.... 之前的代码
app.get('/test/3'
, (req, res
) =>
{
setTimeout((
) =>
{
res.send('成功返回'
)
}
, 3000
) // 延迟三秒返回,使其中一个盒子请求被取消
}
)
// html
<div class="box" id="abortable1">我的请求1秒后被取消</div>
<div class="box" id="abortable2">我的请求5秒后被取消</div>
<script>function getRequest (url, callback, timeout = 5000, abortCallBack = () =>{}) {const xhr =new XMLHttpRequest()setTimeout(() =>{xhr.abort()abortCallBack()}, timeout)xhr.open('GET', url, true)xhr.onreadystatechange =function () {if (xhr.readyState === 4 && xhr.status === 200) {const res = xhr.responseTextcallback(res)}}xhr.send()}// 超时时间设置为 1 秒,该元素的请求将由于超时被取消getRequest('http://39.105.227.198:1234/test/3', (res) =>{document.querySelector('#abortable1').innerHTML = res}, 1000, () =>{document.querySelector('#abortable1').innerHTML = '我的请求被取消'})// 超时事件为 5 秒,将被正常修改getRequest('http://39.105.227.198:1234/test/3', (res) =>{document.querySelector('#abortable2').innerHTML = res})
</script>

运行结果如图:
在这里插入图片描述
可以看到第一个元素的请求由于超时被取消,第二个元素正确返回并修改了文字。

五、完整代码

以下代码集成了本文章的三个例子,并对请求进行了简单的封装,可以直接运行:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.box {background: pink;width: 300px;height: 30px;line-height: 30px;margin: 10px 0;}</style></head><body><div id="app"></div><input id="charInput" placeholder="请输入一个小写字母" type="text"><div id="suggest">no suggest</div><div class="box" id="abortable1">我的请求1秒后被取消</div><div class="box" id="abortable2">我的请求5秒后被取消</div><script>function getRequest (url, callback, timeout = 5000, abortCallBack = () =>{}) {const xhr =new XMLHttpRequest()setTimeout(() =>{xhr.abort()abortCallBack()}, timeout)xhr.open('GET', url, true)xhr.onreadystatechange =function () {if (xhr.readyState === 4 && xhr.status === 200) {const res = xhr.responseTextcallback(res)}}xhr.send()}inputChange = (str) =>{getRequest(`http://39.105.227.198:1234/test/2?char=${str}`, (res) =>{document.querySelector('#suggest').innerHTML = res})}document.querySelector('#charInput').addEventListener('input', (e) =>inputChange(e.target.value))getRequest('http://39.105.227.198:1234/test/1', (res) =>{document.querySelector('#app').innerHTML = res})getRequest('http://39.105.227.198:1234/test/3', (res) =>{document.querySelector('#abortable1').innerHTML = res}, 1000, () =>{document.querySelector('#abortable1').innerHTML = '我的请求被取消'})getRequest('http://39.105.227.198:1234/test/3', (res) =>{document.querySelector('#abortable2').innerHTML = res})</script></body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/928259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识付费网站搭建微信营销的功能

前段时间&#xff0c;写程序时&#xff0c;出了错误&#xff0c;竟然没有想到是自己属性命名的问题&#xff0c;哎~~~真是一定要注意规范呀&#xff0c;在这里我从网上找了些&#xff0c;规范作为参考 Sun 推荐的命名规范 1 &#xff0c;类名要首字母大写&#xff0c;后面的单词…

公司网站php天河网站建设哪家好

文章目录 1. TSP案例引入2. 考虑惰性约束的求解效率对比2.1 求解基础TSP模型2.2 基于SCIP的Conshdlr添加惰性约束1. TSP案例引入 在运筹学建模和求解过程中,“lazy constraints”(惰性约束)是一种动态添加约束的策略,松弛部分约束后求解得到的“可行解”,不断地进行可行性…

ROM和RAM

1.1计算机中有两种存储器 (1)内存:内存与CPU接轨比较紧密,内存可以被CPU直接访问,内存可按照字节单位来随机访问,程序运行时离不开内存,程序中的变量都是定义在内存中,内存受限于物理技术和成本,容量比较小而…

深入解析:C#学习26天:内存优化的几种方法

深入解析:C#学习26天:内存优化的几种方法pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

电子商务网站建设 代码学校诗歌网站建设

在存在缓存的情况下&#xff0c;删除较前的slide&#xff0c;会出现当前slide与后一个slide重复出现的情况 假设当前存在5个slide&#xff0c;且这5个slide已缓存&#xff0c;则删除slide2后&#xff0c;仍为5个slide&#xff0c;且slide2的内容变为slide3的内容&#xff0c;此…

老板合作网站开发网销怎么做

日常工作中经常需要确定各个指标的权重&#xff0c;利用熵值法确定权重属于客观赋权法&#xff0c;从数据出发&#xff0c;避免过强的主观性&#xff0c;但是也同时带来了一些问题。在某个论坛的帖子中&#xff0c;作者提出了这样的一个问题&#xff1a;“熵值法用于确定权重是…

整理数据制作 直方图,箱须图,概率密度估计(KDE)图

1.导入库和设置 import math import numpy as np import matplotlib.mlab as mlab import matplotlib.pyplot as plt plt.rcParams[font.sans-serif]=[SimHei] # 设置中文字体,作用设置 matplotlib 使用中文字体显示…

云原生应用架构设计原则与落地实践:从理念到便捷的方法论

云原生应用架构设计原则与落地实践:从理念到便捷的方法论pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…

做装饰公司网站6wordpress添加直达链接

问题描述&#xff1a;边缘计算设备是什么意思。 问题解答&#xff1a; 边缘计算&#xff08;Edge Computing&#xff09;是一种计算模型&#xff0c;其主要思想是在距离数据产生源头更近的地方进行数据处理和计算&#xff0c;而不是将所有数据传输到远程云服务器进行处理。边…

基于本地模型+多级校验设计的高效缓存,有效节省token数量(有点鸡肋doge) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

UCosIII 在 Tang Nano 20K 的 SparrowRV 软核移植

一直想完整的完成从FPGA到RTOS再到基础APP完成整个流程的理解,于是,尝试在开源的小麻雀操作系统上移植最简单的UCos-III移植,但由于不懂Verilog,所以磕磕碰碰,以下是其记录: 准备工作 由于使用的是一块小小的 Ta…

学做网站培训班要多少钱家电网站源码

2019独角兽企业重金招聘Python工程师标准>>> 1.安装oracle客户端 2.配置文件 加增一个数据库的方式,是编辑 tnsnames.ora文件,在C:\Oracle\Ora81\NETWORK\ADMIN 目录下. 增加类似下面的信息 SVR236 (DESCRIPTION (ADDRESS_LIST (ADDRESS (PROTOCOL …

深入解析:Elasticsearch的集群管理介绍

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

SIP抓包工具 SIP抓包 SIP抓包

SIP抓包工具 SIP抓包 SIP抓包 CentOS 环境 sngrep 安装及使用在呼叫中心类应用开发过程中,经常需要对 SIP 信令抓包,分析排查问题。通常抓包的工具非常多样,如 Wireshark、tcpdump、ngrep 等都是可选项,但是针对…

2025声级计厂家最新权威推荐排行榜单! 数字声级计,精密声级计,防爆声级计,手持式声级计,剂量声级计公司推荐!

在噪声污染愈发受到重视的当下,从工业生产的机器轰鸣到城市交通的持续喧嚣,从建筑施工的阵阵嘈杂到日常环境中的各类声响,准确监测噪声强度成为管控污染的核心环节。而声级计作为专业测量工具,其品类丰富多样 ——…

US$78.85 KEYDIY KD ZB10-4 Universal Smart Remote Key (Start) 4 Buttons for Honda Type 5pcs/lot

KEYDIY KD ZB10-4 Universal Smart Remote Key (Start) 4 Buttons for Honda Type 5pcs/lot Manufacturer: KEYDIY Condition: New Buttons: 4 Color: Black Proximity / Smart / Keyless Go: Yes KEYDIY Remote Serie…

怎么套模板做网站建设众筹类网站

导航引言一、什么是配置中心二、常见的配置中心组件三、Nacos Config 入门四、Nacos Config 动态配置4.1 硬编码方式&#xff08;默认支持动态生效&#xff09;4.2 属性注入五、配置共享5.1 相同微服务不同环境间共享5.2 不同微服务配置共享六、Nacos Config 的几个概念总结引言…

深圳图派做的网站后台加什么做网站用win2008系统

作为DBA工作中都会遇到过数据库服务器CPU飙升的场景&#xff0c;我们该如何快速定位问题&#xff1f;又该如何快速找到具体是哪个SQL引发的CPU异常呢&#xff1f;下面我们说两个方法。聊聊MySQL中如何快速定位占用CPU过高的SQL。 技术人人都可以磨炼&#xff0c;但处理问题的思…

CPP中CAS std::chrono 信号量与Any类的手动达成

CPP中CAS std::chrono 信号量与Any类的手动达成2025-10-05 12:14 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display:…