入门AJAX——XMLHttpRequest(Post)

article/2025/6/9 12:33:12

一、前言

在上篇文章中,我们已经介绍了 HMLHttpRequest 的GET 请求的基本用法,并基于我提供的接口练习了两个简单的例子。如果你还没有看过第一篇文章,强烈建议你在学习完上篇文章后再学习本篇文章:
🔗入门AJAX——XMLHttpRequest (Get)

本篇文章,我们将介绍 POST 请求,并练习一个简单的例子,同样的,我将提供远程接口,你可以直接调用,也可以跟着我搭建本地后端。

前置知识

在本篇文章学习之间,请确认你对以下概念已经具备了基础了解:

  • 网络请求: POST,请求头请求体。
  • 一些基础的 dom 操作
  • 对于代码具有封装的意识

完整代码在文末

二、本文任务

实现简单的删除功能:页面上设置两个按钮和一个搜索框;两个按钮分别用于获取列表和删除列表的元素。开始时,我们获取后端的全部列表信息,然后我们可以在输入框内输入想要删除的元素,点击删除按钮后向服务器发送 POST 请求删除元素(其实是将该元素过滤掉后返回)。页面布置如图:
在这里插入图片描述
我们将首先搭建本地的后端服务器,然后书写前端代码实现该逻辑。当然如果你选择使用我提供的远程接口,那么你可以跳过下一节的服务器接口搭建内容。

三、本地服务器接口

如果你没有看过上一篇的内容,再次建议你首先去学习上篇文章的知识:🔗入门AJAX——XMLHttpRequest (Get) 我们在这里直接贴代码:

// app.js
const express = require('express')
const cors = require('cors')
const app = express()app.use(cors())
app.use(express.json())app.post('/post/del', (req, res) => {const delChar = req.body?.delCharif (delChar) {res.send(arr.filter(item => item !== delChar))} else {res.send(arr)}
})app.listen(1234, () => {console.log('服务器运行在 http://localhost:1234')
})const arr = ['喜羊羊','美羊羊','懒羊羊','沸羊羊','暖洋洋','村长'
]

逻辑比较简单,主要是做了一个列表的过滤,我相信你一定看得懂。

三、前端设计

前端页面搭建更为简单,我们需要着重介绍的是 script 部分。依照上面的效果图,编写以下代码:

<button id="getBtn">获取数组</button>
<input type="text" >
<button id="delBtn">确认删除</button><div style="margin-top: 30px;">后端列表:</div>
<ul id = 'list-container'></ul>
<script>// js 代码
</script>

首先我们知道发起请求后我们会获取到一个列表,我们需要把列表的元素循环插入到 ul 中,我们先实现这样一个设置列表函数 setList 它将接受一个列表作为参数,我们将列表元素插入到 ul 中 :

function setList(list) {const container = document.getElementById('list-container')container.innerHTML = ''list.forEach(item => {const child = document.createElement('li')child.innerText = itemcontainer.appendChild(child)})
}

接下来我们给两个按钮绑定事件,每次点击都会向服务器发送请求:

// 如果你是用的是我提供的远程接口
// 请将 url 改为: http://39.105.227.198:1234/post/del
const url = 'http://localhost:9000/post/del'document.getElementById('getBtn').addEventListener('click', () => {postRequest(url, {}, setList)
})document.getElementById('delBtn').addEventListener('click', () => {const value = document.getElementsByTagName('input')[0].valuevalue && postRequest(url, {delChar: value}, setList)
})

他们两个按钮都会调用到一个 postRequest 的函数,只不过穿进去的第二个参数有所不同。第二个参数我们规定为负载,将最为请求体以 JSON 的格式传到接口,接口将根据该数据确定要删除(过滤)哪一个元素。而第一个按钮我们需要获取全部元素,故第二个参数为空对象。

现在让我们开始编写 postRequest 函数吧:

function postRequest(url, body, callback) {const xhr = new XMLHttpRequest()// 请求方法为 POST xhr.open('POST', url, true)// 通过请求头明确告知服务器本次请求携带的数据为 JSON 格式xhr.setRequestHeader('Content-Type', 'application/json')xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {// 服务器成功返回后,将返回的列表作为参数传递给回调函数,在这里也就是 setList 函数callback(JSON.parse(xhr.responseText))}}// 把将要被删除的数据转为 JSON 字符串作为请求体发送到服务器xhr.send(JSON.stringify(body))
}

四、效果

当我们刚进入页面时,页面上没有任何数据:
在这里插入图片描述
然后我们点击获取数组按钮,可以在下面看到后端返回的列表数据,同时浏览器发起了一次 POST请求(图片中的端口是 9000,不必在意,成功即可):

在这里插入图片描述
然后我们试着删除一个元素“沸羊羊”,我们需要在输入框内输入“沸羊羊”,然后点击确认删除,发现列表中对应的元素已经被删除,并且浏览器再次发送了一条 POST 请求,该请求携带了我们要删除的与与元素:
在这里插入图片描述

五、完整代码

<!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="getBtn">获取数组</button><input type="text" ><button id="delBtn">确认删除</button><div style="margin-top: 30px;">后端列表:</div><ul id = 'list-container'></ul><script>// 如果你是用的是我提供的远程接口// 请将 url 改为: http://39.105.227.198:1234/post/delconst url = 'http://localhost:9000/post/del'function postRequest(url, body, callback) {const xhr = new XMLHttpRequest()xhr.open('POST', url, true)xhr.setRequestHeader('Content-Type', 'application/json')xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {callback(JSON.parse(xhr.responseText))}}xhr.send(JSON.stringify(body))}function setList(list) {const container = document.getElementById('list-container')container.innerHTML = ''list.forEach(item => {const child = document.createElement('li')child.innerText = itemcontainer.appendChild(child)})}document.getElementById('getBtn').addEventListener('click', () => {postRequest(url, {}, setList)})document.getElementById('delBtn').addEventListener('click', () => {const value = document.getElementsByTagName('input')[0].valuevalue && postRequest(url, {delChar: value}, setList)})</script>
</body>
</html>

六、写在后面

随着技术的不断发展,像 XMLHttpRequest 这类底层方法的直接使用率已逐渐降低,取而代之的是更高效简洁的 fetch API,以及更多封装完善的库(如 axios)。这些工具使用便捷、功能集成度高,既无需开发者反复编写冗余代码,也不必操心底层实现原理。

然而,XMLHttpRequest 的学习仍有其必要性。作为前端开发工程师,若仅停留在“调库”层面,核心竞争力将难以体现。理解底层原理(如 HTTP 请求生命周期、状态管理、异步机制等),能够帮助开发者更精准地定位问题、优化请求逻辑,甚至在面对复杂场景时自主实现定制化解决方案。毕竟,框架与库的本质是“工具”,而扎实的基础才是技术深度的核心体现。


http://www.hkcw.cn/article/yajyncLloD.shtml

相关文章

网络交换机:构建高效、安全、灵活局域网的基石

在数字化时代&#xff0c;网络交换机作为局域网(LAN)的核心设备&#xff0c;承担着数据转发、通信优化和安全防护的关键任务。其通过独特的MAC地址学习、冲突域隔离、VLAN划分等技术&#xff0c;显著提升了网络性能&#xff0c;成为企业、学校、医院等场景不可或缺的基础设施。…

《深入解析SPI协议及其FPGA高效实现》-- 第三篇:FPGA实现关键技术与优化

第三篇&#xff1a;FPGA实现关键技术与优化 聚焦高速时序、资源复用与信号完整性 1. 时序收敛关键策略 1.1 源同步时序约束 tcl # Vivado XDC约束示例 create_generated_clock -name spi_sck -source [get_pins clk_gen/CLKOUT] \-divide_by 1 [get_ports sck]# 建立时间约…

EtherCAT背板方案:方芯半导体工业自动化领域的高速、高精度的通信解决方案

前言&#xff1a;EtherCAT背板方案是一种插拔式设计方案&#xff0c;ESC&#xff08;EtherCAT从站控制器&#xff09;之间通过底板信号线相互连接。底板信号线为所支撑的器件提供电源和数据信号。ESC芯片多级从站之间通过LVDS&#xff08;低压差分信号&#xff09;接口相连接&a…

TablePlus:一个跨平台的数据库管理工具

TablePlus 是一款现代化的跨平台&#xff08;Window、Linux、macOS、iOS&#xff09;数据库管理工具&#xff0c;提供直观的界面和强大的功能&#xff0c;可以帮助用户轻松管理和操作数据库。 TablePlus 免费版可以永久使用&#xff0c;但是只能同时打开 2 个连接窗口&#xff…

记我的第一个深度学习模型尝试——MNIST手写数字识别

种一棵树最好的时间是十年前&#xff0c;其次是现在。 目录 前言 一、数据准备 二、构建模型 三、模型精度检验 前言 最近又空闲下来&#xff0c;终于有时间把之前荒废的学习计划给重拾起来了&#xff01;今天做的是MNIST手写数字识别项目。这可以说是深度学习的“Hello Wo…

杭州白塔岭画室怎么样?和燕壹画室哪个好?

杭州作为全国美术艺考集训的核心区域&#xff0c;汇聚了众多实力强劲的画室&#xff0c;其中白塔岭画室和燕壹画室备受美术生关注。对于怀揣艺术梦想的考生而言&#xff0c;选择一所契合自身需求的画室&#xff0c;对未来的艺术之路影响深远。接下来&#xff0c;我们将从多个维…

AI与区块链:数据确权与模型共享的未来

AI与区块链&#xff1a;数据确权与模型共享的未来 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 AI与区块链&#xff1a;数据确权与模型共享的未来摘要引言技术路线对比1. 数据确权&#xff1a;从中心化存储到分布…

【T2I】Decouple-Then-Merge: Finetune Diffusion Models as Multi-Task Learning

CODE: CVPR 2025 GitHub - MqLeet/DeMe: [CVPR2025] Official implementation of "Decouple-Then-Merge: Finetune Diffusion Models as Multi-Task Learning" Abstract 扩散模型是通过学习一系列模型来训练的&#xff0c;这些模型可以逆转噪声衰减的每一步。通常&…

二分查找的边界艺术:LeetCode 34 题深度解析

文章目录 一、问题引入&#xff1a;寻找区间的边界二、二分的核心&#xff1a;二段性三、左边界的查找逻辑&#xff08;找第一个 ≥ target 的位置&#xff09;四、右边界的查找逻辑&#xff08;找最后一个 ≤ target 的位置&#xff09;五、代码实现六、二分边界模板总结结语 …

系统思考:短期利益与长期系统影响

一个决策难题&#xff1a;一家公司接到了一个大订单&#xff0c;客户提出了10%的降价要求&#xff0c;而企业的产能还无法满足客户的需求。你会选择增加产能&#xff0c;接受这个订单&#xff0c;还是拒绝&#xff1f;从系统思考的角度来看&#xff0c;这个决策不仅仅是一个简单…

【数据结构 -- B树】

目录 一、前言二、B树示例定义查找数据插入数据删除数据 一、前言 前面我们已经学习了二叉搜索树和AVL树&#xff0c;它们的查找、插入、删除数据效率都很高&#xff0c;我们首先需要了解它们是怎么操作数据的 首先将所有数据一次性调到内存中&#xff0c;再在内存中进行处理…

新手小白使用VMware创建虚拟机练习Linux

新手小白想要练习linux&#xff0c;找不到合适的地方&#xff0c;可以先创建一个虚拟机&#xff0c;在自己创建的虚拟机里面进行练习&#xff0c;接下来我给大家接受一下创建虚拟机的步骤。 VMware选择创建新的虚拟机 选择自定义 硬件兼容性选择第一个&#xff0c;不同的版本&a…

C++ Vector算法精讲与底层探秘:从经典例题到性能优化全解析

前引&#xff1a;在C标准模板库&#xff08;STL&#xff09;中&#xff0c;vector作为动态数组的实现&#xff0c;既是算法题解的基石&#xff0c;也是性能优化的关键战场。其连续内存布局、动态扩容机制和丰富的成员函数&#xff0c;使其在面试高频题&#xff08;如LeetCode、…

【macbook】触控板手势

在 MacBook 上&#xff0c;你可以使用「触控板手势」或快捷键来实现在多个窗口/应用间切换&#xff0c;以下是几种方式&#xff1a; ✅ 1. 三指或四指左右滑动&#xff1a;切换“全屏应用”或“桌面”空间 **操作方式&#xff1a;**三指或四指在触控板上左右滑动。**适用场景&…

帝可得 - 策略管理

一. 需求说明 策略管理主要涉及到二个功能模块&#xff0c;业务流程如下&#xff1a; 新增策略: 允许管理员定义新的策略&#xff0c;包括策略的具体内容和参数&#xff08;如折扣率&#xff09; 策略分配: 将策略分配给一个或多个售货机。 graph TDA[登录系统] A --> B…

立志成为一名优秀测试开发工程师(第十一天)—Postman动态参数/变量、文件上传、断言策略、批量执行及CSV/JSON数据驱动测试

目录 一、Postman接口关联与正则表达式应用 1.正则表达式解析 2.提取鉴权码。 二、Postman内置动态参数以及自定义动态参数 1.常见内置动态参数&#xff1a; 2.自定义动态参数&#xff1a; 3.“编辑”接口练习 三、图片上传 1.文件的上传 2.上传后内容的验证 四、po…

学习路之PHP--easyswoole使用视图和模板

学习路之PHP--easyswoole使用视图和模板 一、安装依赖插件二、 实现渲染引擎三、注册渲染引擎四、测试调用写的模板五、优化六、最后补充 一、安装依赖插件 composer require easyswoole/template:1.1.* composer require topthink/think-template相关版本&#xff1a; "…

【C++高并发内存池篇】性能卷王养成记:C++ 定长内存池,让内存分配快到飞起!

&#x1f4dd;本篇摘要 在本篇将介绍C定长内存池的概念及实现问题&#xff0c;引入内存池技术&#xff0c;通过实现一个简单的定长内存池部分&#xff0c;体会奥妙所在&#xff0c;进而为之后实现整体的内存池做铺垫&#xff01; &#x1f3e0;欢迎拜访&#x1f3e0;&#xff…

前端验证下跨域问题(npm验证)

文章目录 一、背景二、效果展示三、代码展示3.1&#xff09;index.html3.2&#xff09;package.json3.3&#xff09; service.js3.4&#xff09;service2.js 四、使用说明4.1&#xff09;安装依赖4.2&#xff09;启动服务器4.3&#xff09;访问前端页面 五、跨域解决方案说明六…

nginx+Tomcat负载均衡群集

目录 一. LVS&#xff0c;HAProxy&#xff0c;Nginx的区别 1. 核心区别 2. 负载均衡算法对比 2. 1 LVS 负载均衡算法 2.2 HAProxy 负载均衡算法 2.3 Nginx 负载均衡算法 2.4 总结 二. 案例分析 1. 案例概述 (1) Tomcat 简介 (2)应用场景 2. 案例环境 3. 案例实施 …