← 返回目录

5. POST 请求与同步/异步原理

POST 和 GET 最大的区别在哪?GET 把参数写在门牌号上(URL 里,谁都能看到),POST 把参数揣兜里(请求体里,外面看不见)。所以密码、身份证这种敏感信息必须用 POST——总不能把密码写在网址上让所有人看到吧。

另外这节课还要搞懂同步和异步的区别:同步 = 单车道堵车,后面全等着;异步 = 多车道并行,各走各的。项目里 99% 用异步,因为同步会把页面卡死。

5.1 互动演示(模拟 POST 登录)

账号 密码
点登录,看 POST 请求体的组装方式(本地模拟,实际开发需后端接口)。

5.2 知识点讲解

① POST 请求三要素(少一个都不行)

POST 和 GET 写法很像,但有三个关键区别,缺一不可:

let xhr = new XMLHttpRequest(); // 叫一个新的送货小哥,这次用 POST

// 第①个区别:open 第一个参数写 "post"
// 第二个参数只写接口地址,参数不拼在 URL 上!
xhr.open("post", "http://xxx/api/login", true); // 告诉小哥:用 POST 方式去这个地址拿货

// 第②个区别:必须设置表单请求头(★ 最容易忘的一步!)
// 告诉后端:"我传的参数是 key=value&key=value 格式的"
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 给小哥戴胸牌,说明兜里装的是表单格式

// 第③个区别:参数放在 send 里,不拼在 URL 上
// 格式:name=张三&age=18(和 GET 拼 URL 的格式一样,但位置不同)
let params = "username=zhangsan&password=123456"; // 把账号密码拼成字符串,揣兜里

// 监听部分和 GET 一模一样
xhr.onreadystatechange = function () { // 货到了打电话给你
  if (xhr.readyState === 4 && xhr.status === 200) { // 4=货拿完了 且 200=服务器说没问题
    let res = JSON.parse(xhr.responseText); // 把后端回信翻译成 JS 对象
    console.log("登录结果", res); // 打印登录结果
  }
};

// send 里塞参数(GET 是空的,POST 是有参数的)
xhr.send(params); // 让小哥出发,兜里揣着账号密码

如果你忘了写 setRequestHeader("Content-Type", ...),后端就不知道你传的是什么格式,参数全收不到——因为后端默认按表单格式去解析请求体,你不说清楚它就懵了。POST 三要素:参数不拼 URL、必写请求头、参数放 send

② GET 和 POST 核心区别(一张表搞定)

对比维度GET(写在门牌号上)POST(揣兜里)
传参位置参数拼在 URL 上,地址栏明文可见,谁都能看到参数放 send 里的请求体,地址栏看不到
安全性密码写在 URL 上 = 所有人都能看到,绝对不行地址栏看不到,敏感数据优先用 POST
数据大小URL 长度有限制(浏览器约 2000 字符),只能传少量简单参数没有硬性上限,适合上传文件、批量表单、大段文本
字符支持URL 只支持英文和数字,中文要编码支持全部字符,包括二进制文件
缓存浏览器会自动缓存,参数留在历史记录里不缓存、不留历史记录

记不住就想生活场景:查资料、翻页、搜索 = GET(看一下,不改动);登录、注册、提交订单、上传 = POST(动真格的,要传敏感数据)。

③ 同步 vs 异步:单车道 vs 多车道

同步异步的区别就在 xhr.open 的第三个参数:

// xhr.open 的第三个参数:
//  true = 异步(项目 99% 用这个)
//  false = 同步(极少用,会卡死页面!)

// ===== 异步原理(多车道并行) =====
// 你把请求发出去后,JS 不等后端返回,继续往下执行下一行代码
// 网络请求在浏览器后台偷偷进行
// 等数据到了,再触发 onreadystatechange 回调
// 好处:页面能正常点、能滚、不卡

// 类比:多车道高速,一条车道堵了,其他车道照样通行
// 你发了请求 → 继续干别的 → 货到了回调通知你

// ===== 同步原理(单车道堵车) =====
// send 之后,整个 JS 代码直接停住!
// 页面所有交互全部冻结:不能点按钮、不能滚页面、不能输入
// 必须等服务器完整返回数据,才继续往下走
// 坏处:网络慢的话,页面白屏卡死好几秒

// 类比:单车道高速,前方事故堵车,后面所有车原地等
// 你发了请求 → 站着死等 → 货到了才能继续

如果你把 open 第三个参数写成 false(同步),网络一慢页面就白屏卡死,用户以为浏览器崩了——因为同步会阻塞 JS 的主线程。项目里 99% 用异步(true),同步基本只在一些特殊工具场景用。

④ 实战:用在哪 / 常见坑 / 怎么解决

可能在什么地方用:

① 登录、注册、修改密码等敏感操作用 POST;② 上传文件、提交大段文本用 POST;③ 翻页、搜索、查看列表用 GET。

常见的问题:

① POST 忘了写 setRequestHeader("Content-Type", ...),后端收不到参数;② POST 参数拼到 URL 上去了,后端从请求体里找不到;③ 把 open 第三个参数写成 false(同步),页面卡死;④ 密码用 GET 传,地址栏明文暴露。

解决思路:

① POST 三要素背熟:不拼 URL + 必写 Content-Type + 参数放 send;② 敏感数据一律 POST;③ open 第三参永远写 true(异步),除非有特殊理由。

一句话:POST 参数放 send + 必写表单请求头,更安全;open 第三参 true = 异步不卡页面,false = 同步会卡死;密码用 POST 不用 GET。

5.3 课后作业(融入本节)

练习一:POST 登录——新建 demo1.html,页面包含用户名输入框、密码输入框、登录按钮。用原生 AJAX 发 POST 请求到 http://bas.xingyuncm.cn/webapi/index/user,参数为 account 和 password,登录成功把 id 存到 localStorage。

练习二:同步 vs 异步对比——① 异步请求,在 send 后面立刻 console.log("请求已发送"),看输出顺序;② 把 open 第三参改成 false(同步),再看输出顺序和页面反应;③ 在注释里总结为什么异步是首选。