如何使用javascript与后端服务器通信?【教程】

14次阅读

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

如何使用 javascript 与后端服务器通信?【教程】

JavaScript 与 后端 通信,核心就两条路:fetchXMLHttpRequest,现代项目基本只用 fetch;但如果你在维护老代码或需要兼容 IE,才得碰 XMLHttpRequest

fetch 发 GET 请求最简写法

fetch 默认就是 GET,传个 URL 就能发,但要注意它不会自动抛错——哪怕后端返回 404 或 500,fetch 仍算“成功”,得手动检查 response.okresponse.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 里手写,用 URLSearchParamsfetch(`/api/users?${new URLSearchParams({ page: '1', limit: '10'})}`)
  • 不加 credentials: 'include'跨域 请求带不了 Cookie,登录态就断了

fetch 发 POST 提交 JSON 数据

发 JSON 是最常见场景,关键在两件事:设对 Content-Type 头,且把 JS 对象转成字符串再发。

容易踩的坑:

  • 漏写 headers: {'Content-Type': 'application/json'},后端可能收不到 body
  • 直接传对象给 bodybody: {name: 'a'} —— 这会报错,必须 body: JSON.stringify({name: 'a'})
  • 后端返回 204 No Content 时,调 .json() 会失败,得先判断 res.headers.get('content-type')?.includes('json')

示例片段:

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)。

但注意:XMLHttpRequestonload 不会捕获 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,而不是每个地方都写重复逻辑。

text=ZqhQzanResources