从 AJAX 到 axios:前端与服务器通信实战指南

直到现在我们小宁已经更新了44作品了,其中和大家介绍了Python入门基础、Fast API框架、SQLite数据库,以及前端的知识都已经学习完了,总的来说现在前端、后端、数据库已经都学习了,那大家是否有这样的疑问,前端后端到底应该怎么联系起来使用呢?

在现代 Web 开发中,网页不再是静态的信息展示板,而是能与服务器实时交互的动态应用。实现这一功能的核心技术就是 AJAX,而 axios 则是简化 AJAX 操作的利器。本文从基础概念到实战案例,带你掌握前端与服务器通信的全流程。

一、认识 AJAX:让数据 “动” 起来

1. 什么是 AJAX?

AJAX(Asynchronous JavaScript and XML)是一种通过浏览器的 XMLHttpRequest 对象与服务器异步通信的技术。它能让网页在不刷新的情况下,向服务器请求数据并更新页面内容。

例如,当你在网页上点击 “查询省份” 按钮时,浏览器通过 AJAX 向服务器发送请求,服务器返回省份列表数据,前端直接将数据展示在页面上,整个过程无需刷新页面。

2. 为什么需要 AJAX?

传统网页的数据是固定写在代码中的,无法实时更新。有了 AJAX,数据可以从服务器动态获取,让页面内容 “活” 起来。比如:实时显示最新的省份 / 城市列表、用户登录状态验证等。

3. 为什么选择 axios?

AJAX 底层依赖 XMLHttpRequest 对象,但语法繁琐。axios 是一个基于 Promise 的 HTTP 客户端,语法简洁,且在 Vue 等框架中被广泛使用,能让我们更专注于业务逻辑而非底层通信细节。

二、URL:定位服务器资源的 “地址”

要与服务器通信,首先需要知道资源的位置 ——URL(统一资源定位符)。

1. URL 的核心组成

一个完整的 URL 包含三个关键部分:

  • 协议:如 http://,规定浏览器与服务器的通信规则;
  • 域名 / IP:如 127.0.0.1:8000,标记服务器在网络中的位置;
  • 资源路径:如 /api/province,指定服务器上具体资源的位置。

例如,http://127.0.0.1:8000/api/province 表示:通过 HTTP 协议,访问本地服务器(127.0.0.1:8000)上的省份列表资源。

2. axios 中携带查询参数

在 axios 中,通过 params 选项设置查询参数,无需手动拼接 URL:

// 获取辽宁省的城市列表
axios({url: 'http://127.0.0.1:8000/api/city',params: {pname: '辽宁省' // 参数名与服务器要求一致(课件中服务器约定参数名为pname)}
}).then(result => {// 服务器返回的数据格式为 { list: [城市1, 城市2, ...] }console.log('辽宁省城市列表:', result.data.list); // 渲染到页面:将城市列表转为li标签document.querySelector('ul').innerHTML = result.data.list.map(city => `<li>${city}</li>`).join('');
});

三、请求方法和常见报错:与服务器的 “交互方式”

HTTP 协议定义了多种请求方法,用于表示对服务器资源的操作。常用方法如下:

请求方法作用示例
GET获取资源(如查询数据)查询省份列表
POST提交数据(如注册、登录)用户注册
PUT全量更新资源修改用户所有信息
DELETE删除资源删除一条记录

HTTP 常见响应状态码(错误码)说明

状态码类别含义说明常见场景示例
200成功请求成功,服务器正常返回数据登录成功、查询数据成功
400客户端错误请求参数错误或格式不正确用户名不符合规则(如长度不足)
401客户端错误未授权,需要验证身份(如登录失效)密码错误、未登录访问需要权限的资源
404客户端错误请求的资源不存在访问了错误的 URL(如 /api/xxx 拼写错误)
500服务器错误服务器内部出错,无法处理请求服务器代码报错、数据库连接失败
403客户端错误服务器拒绝请求(如权限不足)普通用户尝试删除管理员数据
408客户端错误请求超时网络延迟导致服务器未及时收到请求
503服务器错误服务器暂时不可用(如维护中)服务器负载过高、正在重启

四、综合案例

1、axios的使用步骤

①引入axios.js文件到自己的网页中:axios 在线引入地址(复制直接使用)

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script>

明确axios函数的使⽤语法

综合语句1:
axios({// 配置项url: '目标地址',method: '请求方法', // 默认为 getparams: {}, // GET 参数data: {}    // POST 参数
})
.then(result => {// 成功回调:处理服务器返回的数据
})
.catch(error => {// 失败回调:处理错误信息
});综合语句2:
axios.请求方法(url:'目标地址',{参数名1:值1;.......
}).then(result => {// 成功回调:处理服务器返回的数据
})
.catch(error => {// 失败回调:处理错误信息
});

2、综合案例代码

 province_API.py:这里有后续网页对应的API接口

from fastapi import FastAPI
# 浏览器出于安全考虑,默认会阻止跨域请求(例如前端运行在 http://localhost:3000,
# 而 API 服务在 http://localhost:8000),这时就需要后端设置 CORS 来允许跨域访问。
from fastapi.middleware.cors import CORSMiddleware
# 用于创建数据库引擎,常用于同步数据库连接
from sqlalchemy import create_engine,Column,Integer,String
# 用于创建数据库会话,用于执行数据库操作
from sqlalchemy.orm import sessionmaker, declarative_base# 创建FastAPI应用
app = FastAPI()# 添加CORS中间件,允许跨域传输
app.add_middleware(CORSMiddleware,allow_origins=["*"],  # 允许所有源allow_credentials=True,  # 是否允许发送 Cookieallow_methods=["*"],  # 允许所有HTTP方法allow_headers=["*"],  # 允许所有HTTP头部
)
# 定义数据库连接URL
DATABASE_URL = "sqlite:///province.db"
# 创建数据库引擎,设置连接参数以允许在多线程环境中使用(地址)
engine = create_engine(DATABASE_URL,connect_args={"check_same_thread": False})
# 创建会话,绑定数据库引擎
SessionLocal = sessionmaker(bind=engine)
# 创建基类
Base = declarative_base()
# 创建数据库表结构(可以创建数据库表结构)
class Province(Base):__tablename__ = "province"code = Column(String)id = Column(Integer, primary_key=True, index=True)name = Column(String, unique=True, index=True)
# 执行创建数据库表结构
Base.metadata.create_all(bind = engine)@app.get("/api/all_province")
def get_all_provinces():"""获取所有省份列表返回格式与前端期望的格式一致,包含list属性"""db = SessionLocal()try:provinces = db.query(Province).all()province_list = [province.name for province in provinces]return {"list": province_list}finally:db.close()@app.get("/api/find_province")
def find_province(name: str):"""根据名称查询省份返回格式与前端期望的格式一致,包含list属性"""db = SessionLocal()try:find_province = db.query(Province).filter(Province.name == name).first()if find_province:return find_province.namereturn "未找到该省份"finally:db.close()# 实现城市查询API接口
@app.get("/api/city")
def get_cities(pname: str = None):"""根据省份名称获取城市列表参数:- pname: 省份名称"""# 这里简化处理,实际应该查询数据库中的城市数据# 为演示目的,返回一些示例城市cities = {"辽宁省": ["沈阳市", "⼤连市", "鞍⼭市", "抚顺市", "本溪市"],"上海": ["上海市"],"⼴东省": ["⼴州市", "深圳市", "珠海市", "汕头市", "佛⼭市"],"北京": ["北京", "东城", "西城", "朝阳", "海淀", "丰台", "石景山", "门头沟", "房山", "通州", "顺义", "昌平"],"天津": ["天津", "和平", "河北", "河东", "河西", "南开", "河北", "和平", "宁河", "东丽", "西青", "津南", "北辰"],}if pname and pname in cities:return {"list": cities[pname]}return {"list": []}
# 实现地区查询API接口
@app.get("/api/area")
def get_areas(cname: str = None):"""根据省份和城市名称获取地区列表参数:- pname: 省份名称- cname: 城市名称"""# 这里简化处理,实际应该查询数据库中的地区数据# 为演示目的,返回一些示例地区areas = {"北京市": ["东城区", "西城区", "朝阳区", "海淀区", "丰台区", "石景山区"],"上海市": ["黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区"],"广州市": ["越秀区", "荔湾区", "海珠区", "天河区", "白云区", "黄埔区"],"深圳市": ["福田区", "罗湖区", "南山区", "宝安区", "龙岗区", "盐田区"]}if cname and cname in areas:return {"list": areas[cname]}return {"list": []}if __name__ == "__main__":import uvicornuvicorn.run(app, host="127.0.0.1", port=8080)

data.py:主要用于创建数据库,插入数据库的省份数据

import sqlite3
# 创建数据库连接
conn = sqlite3.connect('province.db')
# 创建数据库游标:游标能够对数据库进行操作
cursor = conn.cursor()
# 创建表
sql = '''
CREATE TABLE IF NOT EXISTS province (id INTEGER PRIMARY KEY,name TEXT NOT NULL,code TEXT NOT NULL
)'''
cursor.execute(sql)
sql = '''
insert into province(name,code)values
('北京', '110000'),
('天津', '120000'),
('河北', '130000'),
('⼭⻄', '140000'),
('内蒙古', '150000'),
('辽宁', '210000'),
('吉林', '220000'),
('⿊⻰江', '230000'),
('上海', '310000'),
('江苏', '320000'),
('浙江', '330000'),
('安徽', '340000'),
('福建', '350000'),
('江⻄', '360000')
'''
cursor.execute(sql)
conn.commit()
conn.close()

 all_province.html:这个页面主要是对应 province_API里面的第一个接口,使用get的请求方式,不带参数来获取数据库的所有省份信息

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>所有的省份信息</title>
</head>
<body><h1>这里是所有的省份信息</h1><p id="all_province"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>axios({url: 'http://127.0.0.1:8080/api/all_province'}).then(result => {// 对服务器返回的数据做后续处理console.log(result)console.log(result.data)console.log(result.data.list)let all_province = document.getElementById('all_province')all_province.innerHTML = result.data.list.join('<br/>')})</script><p></p>
</body>
</html>

 

find_city.html:这个页面主要是对应 province_API里面的第二个接口,使用post的请求方式,带查询城市名称参数来获取地区信息
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>显示城市的各个区</title>
</head>
<body><h1>显示城市的各个区</h1>城市:<input type="text" id="input" placeholder="请输入你要查找的城市"><button id = "btn">查找</button><h2>以下是查找的结果:</h2>省份:<p id="sf"></p>区:<p id="city"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>let input = document.getElementById('input');let btn = document.getElementById('btn');let sf = document.getElementById('sf');let city = document.getElementById('city');btn.addEventListener('click', function () {if (input.value) {axios({url: 'http://127.0.0.1:8080/api/city',params: {pname: input.value}}).then(result => {// 对服务器返回的数据做后续处理// console.log(result)// console.log(result.data)console.log(result.data.list)if (result.data.list.length != 0){sf.innerHTML = input.valuecity.innerHTML = result.data.list.join('<br/>')}else {sf.innerHTML = '没有找到该城市'}})}})</script>
</body>
</html>

 

find_area.html:这个页面主要是对应 province_API里面的第三个接口,使用post的请求方式,带查询城市名称参数来获取地区信息
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>查找地区列表</title><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>案例_地区查询</title>
</head>
<body><h1>显示城市的各个区</h1>城市:<input type="text" id="input" placeholder="请输入你要查找的城市"><button id = "btn">查找</button><h2>以下是查找的结果:</h2>城市:<p id="sf"></p>区:<p id="city"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>const input = document.getElementById('input');const btn = document.getElementById('btn');const sf = document.getElementById('sf');const city = document.getElementById('city');btn.addEventListener('click', function () {if (input.value) {axios({url: 'http://127.0.0.1:8080/api/area',params: {cname: input.value}}).then(result => {// 对服务器返回的数据做后续处理// console.log(result)// console.log(result.data)console.log(result.data.list)if (result.data.list.length != 0){sf.innerHTML = input.valuecity.innerHTML = result.data.list.join('\n')}else {sf.innerHTML = '没有找到该城市'}})}})</script>
</body>
</html>

find_province.html:这个页面主要是对应 province_API里面的第四个接口,使用post的请求方式,带查询数据库中是否存在该城市
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>查找城市是否存在</title>
</head>
<body><input type="text" id="input"><button id="btn">查找</button><p id="find_province"></p><script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.2/axios.min.js"></script><script>let input = document.getElementById('input');let btn = document.getElementById('btn');let find_province = document.getElementById('find_province');btn.addEventListener('click', function () {if (input.value) {axios({url: 'http://127.0.0.1:8080/api/find_province',params: {name: input.value}}).then(result => {// 对服务器返回的数据做后续处理console.log(result)console.log(result.data)find_province.innerText = result.data})}})</script>
</body>
</html>

五、综合案例 2:用户登录(结合 form-serialize)

需求:实现用户登录功能,包含表单验证、数据提交和结果提示,并使用 form-serialize 插件简化表单数据收集。

1. form-serialize 插件介绍

1. 我们前⾯收集表单元素的值,是⼀个个标签获取的
2. 如果⼀套表单⾥有很多很多表单元素,如何⼀次性快速收集出来呢?
3. 使⽤ form-serialize 插件提供的 serialize 函数就可以办到
4. form-serialize 插件语法:
   
  • 引入插件:<script src="https://unpkg.com/form-serialize@0.7.2/form-serialize.min.js"></script>
  • 调用 serialize 函数:serialize(表单元素, { hash: true, empty: true })hash: true 返回对象,empty: true 包含空值)。
参数1:要获取的 form 表单标签对象(要求表单元素需要有 name 属性-⽤来作为收集的
数据中属性名)
参数2:配置对象
        hash:
                true - 收集出来的是⼀个 JS 对象结构
                false - 收集出来的是⼀个查询字符串格式
        empty:
                true - 收集空值
                false - 不收集空值
5. 需求:收集登录表单⾥⽤户名和密码
   <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>form-serialize插件使⽤</title></head><body><form action="javascript:;" class="example-form"><input type="text" name="username"><br><input type="text" name="password"><br><input type="button" class="btn" value="提交"></form><!--/2. 使⽤serialize函数,快速收集表单元素的值参数1:要获取哪个表单的数据表单元素设置name属性,值会作为对象的属性名建议name属性的值,最好和接⼝⽂档参数名⼀致参数2:配置对象hash 设置获取数据结构- true:JS对象(推荐)⼀般请求体⾥提交给服务器- false: 查询字符串empty 设置是否获取空值- true: 获取空值(推荐)数据结构和标签结构⼀致- false:不获取空值/--><!-- 引入 serialize.js 插件 --><script src="https://unpkg.com/form-serialize@0.7.2/form-serialize.min.js"></script><script>document.querySelector('.btn').addEventListener('click', () => {const form = document.querySelector('.example-form');const data = serialize(form, { hash: true, empty: true });// const data = serialize(form, { hash: false, empty: true });// const data = serialize(form, { hash: true, empty: false });console.log(data);});</script></body></html>


 

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

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

相关文章

Pycatia二次开发基础代码解析:面属性控制、视图定向与特征统计的工业级实现

本文将以专业视角深入解析CATIA二次开发中的三个核心类方法&#xff0c;通过详细分析代码实现揭示其在工业设计中的实际应用价值。全文将严格围绕提供的代码展开&#xff0c;不做任何修改或补充。 一、面属性控制&#xff1a;精确可视化表达技术 方法功能解析 color_and_laye…

bmc TrueSight 监控 Oracle 11g 配置

bmc TrueSight 监控 Oracle配置 文章目录 bmc TrueSight 监控 Oracle配置1.将pat加入oinstall和dba组2.创建监控的表空间和临时表空间并告知表空间名称3.将oracle相关系统环境变量加入到监控pat账户的.profile或.bash_profile文件4.登陆Apollo监控web页面&#xff0c;设置基础架…

css实现高度可变、上下边框是渐变色、左右边框是纯色的div容器

效果图&#xff1a; div容器&#xff1a; <div className{styles.container}><div className{styles.content}><div className{styles.inner}><!-- 内容部分 --></div></div> </div> css&#xff1a; .container {float: left;w…

python二维码识别

pyzbar 识别QR二维码 from PIL import Image from pyzbar.pyzbar import decode# 打开图像文件 image_path qr01.jpg # 替换为你的图像路径 image Image.open(image_path)# 解码图像中的二维码 decoded_objects decode(image)# 输出识别结果 for obj in decoded_objects:p…

ZYNQ EMMC/FLASH/SD卡深度性能评测与创新实践

深入探索ZYNQ存储子系统性能,揭示硬件加速下的存储优化之道 一、存储性能为何如此重要? 在基于Xilinx ZYNQ SoC的嵌入式系统中,EMMC、QSPI FLASH和SD卡作为核心存储介质,直接影响系统启动时间、数据吞吐量和用户体验。传统测试方法往往局限于简单读写速度测试,缺乏对真实…

html制作一个简单的表单

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>表单输入练习</title><style></style> </head><body style"background-color: pink;"><div><h2>…

差分对的等长等距

差分对的等长等距: 差分对中两个单端信号的延时差会导致接收端信号的错位&#xff0c;引起差分信号的畸变&#xff0c;同时会产生共模噪声导致接收端差分信号抖动增加。因此差分对设计的一个基本要求就是要尽量保持差分对两条单端线延时相等。 图8-27显示了差分对中两条单端线…

SQL 子查询全位置解析:可编写子查询的 7 大子句

&#x1f50d; SQL 子查询全位置解析&#xff1a;可编写子查询的 7 大子句 子查询可以出现在 SQL 语句的多个关键位置&#xff0c;不同位置的子查询具有独特的行为和限制。以下是系统化总结&#xff1a; &#x1f4cc; 1. WHERE 子句&#xff08;最常用&#xff09; SELECT 列…

C#高级:Winform桌面开发中DataGridView的详解(新)

一、数据填充&#xff08;反射&#xff09; 1.封装 /// <summary> /// 渲染DataGridView /// </summary> /// <param name"dataGridView">被渲染控件</param> /// <param name"list">数据集</param> /// <param …

人脸活体识别2:Pytorch实现人脸眨眼 张嘴 点头 摇头识别(含训练代码和数据集)

人脸活体识别2&#xff1a;Pytorch实现人脸眨眼 张嘴 点头 摇头识别(含训练代码和数据集) 目录 人脸活体识别2&#xff1a;Pytorch实现人脸眨眼 张嘴 点头 摇头识别(含训练代码和数据集) 1. 前言 2.人脸活体识别方法 &#xff08;1&#xff09;基于人脸动作的检测​​ &a…

Webpack 自定义插件开发指南:构建流程详解与实战开发全攻略

一. webpack打包流程 开发 Webpack 插件的第一步&#xff0c;就是明确&#xff1a;我的插件要接入 Webpack 构建流程的哪个阶段&#xff0c;解决什么问题。 了解流程之前首先要了解插件的两个核心概念&#xff1a;compiler&#xff0c;compilation 1. compiler&#xff1a;全局…

本地部署Dify+Ragflow及使用(一)

概念说明 RAGflow&#xff1a; 吃透知识&#xff1a;将企业文档&#xff08;如技术白皮书&#xff09;解析为结构化知识片段。精准检索&#xff1a;当用户提问时&#xff0c;从知识库中召回最相关内容。 模型供应商&#xff1a; 提供大脑&#xff1a;为 Dify 提供生成答案的模…

2025.06.24【R语言】|clusterProfiler安装与常见报错FAQ全解

文章目录 一、clusterProfiler安装方法1. Bioconductor官方推荐2. Conda安装&#xff08;个人推荐 适合服务器/依赖复杂环境&#xff09;3. 检查安装 二、常见依赖包安装三、常见报错与解决方案1. 报错&#xff1a;could not find function "bitr"2. 报错&#xff1a…

【转】PostgreSql的镜像地址

docker.io/postgres 项目中国可用镜像列表 | 高速可靠的 Docker 镜像资源 docker.io/postgrest/postgrest:v12.2.8 linux/amd64 docker.io17.34MB2025-04-04 13:14 346 docker.io/postgrest/postgrest:v12.2.12 linux/amd64 docker.io17.38MB2025-05-27 22:02 79 docker.io…

爬虫005----Selenium框架

在总结爬虫 &#x1f577; 框架之前&#xff0c;先总结一下selenium框架&#xff0c;也可以说是selenium库&#xff0c;在自动化测试中是老生常谈了&#xff08;长时间⌛️不用&#xff0c;已经忘记了&#xff0c;实际测试工作中做UI自动化的也很少了&#xff0c;上次搞UI自动化…

记一次 Kafka 磁盘被写满的排查经历

开篇扯犊子 今天踏进办公听到不是同事的早安&#xff0c;而是“有一个好消息&#xff0c;一个坏消息&#xff0c;你想听哪个&#xff1f;” 我一愣&#xff0c;心想“大早上&#xff0c;就要玩刺激的吗&#xff1f;” 但是还是淡定的回复说“无所谓&#xff0c;哥什么场面没见…

python多线程:各线程的输出在控制台中同一行原因分析

代码例子 import threading import timedef error_worker():print("子线程开始")time.sleep(1)raise Exception("子线程出错了&#xff01;")t threading.Thread(targeterror_worker) t.start()print("主线程继续执行&#xff0c;不受子线程异常影响…

Promptify与ReActAgent

一、Promptify 定位&#xff1a;NLP 任务的「自动化流水线」 1. 解决什么问题&#xff1f; 传统 LLM 应用开发痛点&#xff1a; 反复调试&#xff1a;需手工编写/调整 prompt 格式&#xff08;如调整分隔符、示例数量&#xff09;兼容性差&#xff1a;不同模型需重写适配代码…

如何将视频从 iPhone 发送到 Android 设备

如果您想将视频从 iPhone 发送到 Android 设备&#xff0c;尤其是视频尺寸较大时&#xff0c;您需要一种高效的传输方法。本文将为您提供 7 种实用方法&#xff0c;让您轻松发送大型视频文件或短视频片段&#xff0c;并且不会损失视频质量。 第 1 部分&#xff1a;如何通过 iRe…

Stable Diffusion入门-ControlNet 深入理解 第四课:风格迁移与重绘控制模型——让AI也有“艺术天赋”!

大家好&#xff0c;欢迎回到 Stable Diffusion入门-ControlNet 深入理解 系列的第四课&#xff01; 如果你还没有看过上一课&#xff0c;赶紧补课哦&#xff1a;Stable Diffusion入门-ControlNet 深入理解 第三课。 上一课我们讲解了 ControlNet 结构类模型&#xff0c;今天我…