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

7次阅读

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