ajax实现省市区三级联动的核心是按需加载、逐级依赖:选省份后请求城市列表,选城市后再请求区县列表,全程不刷新页面;html中三个select分别对应省市区,后两级初始禁用;通过fetch监听change事件动态加载数据,并注意清空下级、重置禁用状态、编码参数及后端校验。

用 Ajax 实现省市区三级联动,核心是“按需加载、逐级依赖”:选中省份后请求该省下的城市列表,选中城市后再请求该市下的区县列表。整个过程不刷新页面,数据从后端接口动态获取。
准备结构化的 HTML 选择框
先写好三个 元素,分别对应省、市、区,并设置唯一 id 和初始空选项:
<select id="province"><option value="">请选择省份</option></select><select id="city" disabled><option value="">请选择城市</option></select><select id="district" disabled><option value="">请选择区县</option></select>
注意:后两级默认禁用(disabled),避免用户提前操作;每次加载新数据前清空下级下拉框并重置禁用状态。
绑定 change 事件并发起 Ajax 请求
用原生 fetch 或 XMLHttpRequest 监听选择变化。推荐 fetch(简洁、现代、支持 Promise):
- 监听 #province 的 change:拿到 selectedValue,请求
/api/cities?province=XX - 成功后填充 #city,移除 disabled,并绑定它的 change 事件
- 监听 #city 的 change:拿到 city 值,请求
/api/districts?city=YY - 成功后填充 #district,移除 disabled
示例关键代码(fetch + async/await):
document.getElementById('province').addEventListener('change', async e => {
const province = e.target.value;
const citySelect = document.getElementById('city');
citySelect.innerHTML = '<option value="">请选择城市</option>';
citySelect.disabled = true;
if (!province) return;
try {
const res = await fetch(`/api/cities?province=${encodeURIComponent(province)}`);
const cities = await res.json();
cities.forEach(city => {
const opt = document.createElement('option');
opt.value = city.code;
opt.textContent = city.name;
citySelect.appendChild(opt);
});
citySelect.disabled = false;
} catch (err) {
console.error('加载城市失败', err);
}
});
后端接口设计要清晰、轻量
前端依赖的是结构明确的 JSON 接口,建议统一返回格式:
-
GET /api/provinces → 返回省级列表:
[{"code":"110000","name":"北京市"},{"code":"310000","name":"上海市"}] - GET /api/cities?province=110000 → 返回该省所有地级市
- GET /api/districts?city=110100 → 返回该市所有市辖区/县级市
注意:参数用 编码后的 code(如 110000)而非中文名,避免乱码和歧义;后端应做基础校验(如 province 是否合法),返回空数组而非报错。
增强体验的小细节
真实项目中加几处优化,体验更自然:
- 请求时显示 loading 状态(比如在 select 旁加 加载中... 或禁用+文字提示)
- 失败时给出友好提示(如“暂无城市数据,请检查网络”),而不是静默失败
- 缓存已加载过的城市/区县数据,避免重复请求(例如用 Map 存 {provinceCode: cities})
- 支持初始化回显:若已有省市区 code,可自动触发级联加载并设为选中项
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











