JavaScript后端通信首选fetch,需手动检查response.ok并调用.json()解析;POST需设Content-Type且JSON.stringify;超时和错误需自行封装处理;仅上传进度或IE兼容时用XMLHttpRequest。

JavaScript 与后端通信,核心就两条路:fetch 和 XMLHttpRequest,现代项目基本只用 fetch;但如果你在维护老代码或需要兼容 IE,才得碰 XMLHttpRequest。
用 fetch 发 GET 请求最简写法
fetch 默认就是 GET,传个 URL 就能发,但要注意它不会自动抛错——哪怕后端返回 404 或 500,fetch 仍算“成功”,得手动检查 response.ok 或 response.status。
常见错误:直接 .then(data => console.log(data)),结果打出来是 Response 对象,不是 JSON 数据。必须链上 .json()(或 .text()、.blob())才能读取内容。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 总是用
await fetch(url).then(r => r.json())或更稳妥的const res = await fetch(url); if (!res.ok) throw new Error(res.status); const data = await res.json(); - GET 参数别拼在 URL 里手写,用
URLSearchParams:fetch(`/api/users?${new URLSearchParams({ page: '1', limit: '10' })}`) - 不加
credentials: 'include',跨域请求带不了 Cookie,登录态就断了
用 fetch 发 POST 提交 JSON 数据
发 JSON 是最常见场景,关键在两件事:设对 Content-Type 头,且把 JS 对象转成字符串再发。
容易踩的坑:
- 漏写
headers: { 'Content-Type': 'application/json' },后端可能收不到 body - 直接传对象给
body:body: { name: 'a' }—— 这会报错,必须body: JSON.stringify({ name: 'a' }) - 后端返回 204 No Content 时,调
.json()会失败,得先判断res.headers.get('content-type')?.includes('json')
示例片段:
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。它不是新的编程语言,而是一种使用现有标准的新方法,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。《php中级教程之ajax技术》带你快速
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email: 'u@x.com', password: '123' })
})
处理 fetch 的网络异常和超时
fetch 本身不支持 timeout,网络卡住会一直挂起。也不能捕获 DNS 失败、断网等底层错误——这些会进 catch,但和 HTTP 错误混在一起,不好区分。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 自己封装超时逻辑:用
Promises.race([fetch(...), new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), 8000))]) - 错误分类要细一点:网络异常(
TypeError)、HTTP 错误(res.status >= 400)、解析失败(.json()报错)最好分开处理 - 别依赖
navigator.onLine判断是否联网,它只反映浏览器认为的“在线”状态,实际可能已断连
什么时候还非得用 XMLHttpRequest?
基本只剩两个真实需求:上传进度条(upload.onprogress)、或者需要 abort 正在进行的请求(xhr.abort())且不支持 AbortController(比如 IE 或某些嵌入式 WebView)。
但注意:XMLHttpRequest 的 onload 不会捕获 JSON.parse 错误,而 fetch 的 .json() 会抛出语法错误——这点反而是 fetch 更可控。
如果真要用,别写回调地狱,至少包一层 Promise:
function xhrGet(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => resolve(JSON.parse(xhr.responseText));
xhr.onerror = () => reject(new Error('Network error'));
xhr.send();
});
}
真正麻烦的从来不是“怎么发请求”,而是怎么统一管理 token 刷新、错误重试、缓存策略、取消冗余请求——这些都得在 fetch 外面包一层自己的 client,而不是每个地方都写重复逻辑。










