在JavaScript里,向服务器发送请求数据最直接的方式是使用fetch API,它在现代浏览器中原生支持,返回Promise,配合async/await读起来像同步代码。
如果你接手过老项目,大概见过XMLHttpRequest那个密集型写法,别担心,后端接口数量再多,前端请求的套路就那么几样,下面从方案选择、代码示例到踩坑清单,一次性说透。
js 请求接口数据的方式:fetch与XMLHttpRequest之选
要用js向服务器发数据,先得选工具,浏览器内置的有两套:XMLHttpRequest(简称XHR)和fetch,前者从IE时代就存在,后者是ES2015之后的标准接口,业内专家指出,新项目默认选fetch,只有需要监听上传进度这类特殊场景才考虑XHR。
原生js发送请求:从XHR到fetch的演进
XHR典型写法是四步走:
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/user');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
xhr.send();
这套模式的问题在于回调嵌套和状态管理,fetch把过程压缩成一次调用,返回Promise对象:
fetch('/api/user')
.then(res => res.json())
.then(data => console.log(data));
相比之下,fetch的语法更扁平,如果后端返回的是JSON,一行res.json()就解析完毕,近年来浏览器对fetch的支持趋于一致,大多数线上项目可以直接使用它。
fetch与XMLHttpRequest的优劣势对比
| 对比项 | fetch | XMLHttpRequest |
|---|---|---|
| 语法复杂度 | 简单,Promise链式调用 | 繁琐,事件回调 |
| 默认带凭据 | 不带,需显式配置 | 同源默认带Cookie |
| 上传进度监听 | 不支持原生进度事件 | 支持 |
| 请求中断 | 支持AbortController | 支持abort() |
| 兼容性 | 现代浏览器均支持 | 老版本浏览器支持更全 |
选择其实不复杂:绝大多数请求用fetch,特殊场景用XHR,比如上传大文件需要显示进度条,XHR的upload.onprogress依然好用。
js ajax请求怎么写的实操示例:GET与POST全流程
工具选好,直接看代码,这里以调后端接口为例,把GET和POST两条主路径走一遍。
GET请求:从接口读取数据
GET一般用来查询数据,用fetch可以这么做:
async function getUser(id) {
const response = await fetch(`/api/user?id=${id}`);
if (!response.ok) {
throw new Error(`请求失败:${response.status}`);
}
const data = await response.json();
return data;
}
要注意,fetch只有在网络层报错时才会reject,HTTP状态码404、500同样会走到response返回,所以response.ok这层判断不能省。
fetch post请求示例:向服务器提交数据
POST一般用于新增或提交表单,下面是一段完整的fetch post请求示例:
async function createUser(userInfo) {
const response = await fetch('/api/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(userInfo)
});
const result = await response.json();
return result;
}
很多新手在这里栽跟头:body直接传对象,忘记JSON.stringify,fetch底层会把对象toString,结果变成”[object Object]”,服务端根本解析不出字段。
发送JSON与表单数据的区别
- JSON数据:headers里声明Content-Type为application/json,body用JSON.stringify序列化。
- 普通表单:headers设为application/x-www-form-urlencoded,body用URLSearchParams拼接键值对。
- 文件上传:把FormData对象直接传给body,浏览器会自动补上multipart/form-data边界,不要手动指定Content-Type。
处理服务器响应与异常:别让数据悄悄消失
请求发出去只是第一步,拿到响应、解析数据、处理异常同样关键。
怎么用js接收服务器返回的数据
响应对象上有三个常用解析方法:
- response.json():把响应体按JSON解析,返回Promise,后端给的是对象或数组时用。
- response.text():拿原始字符串,适合接口返回纯文本。
- response.blob():拿二进制流,下载文件时用。
一个典型场景:
const response = await fetch('/api/order/export');
if (response.ok) {
const blob = await response.blob();
const url = URL.createObjectURL(blob);
window.location.href = url;
}
请求超时与主动中断
fetch没有内置超时配置,需要结合AbortController实现:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('/api/data', {
signal: controller.signal
});
// 正常处理
} catch (err) {
if (err.name === 'AbortError') {
console.log('请求超时,已中断');
}
} finally {
clearTimeout(timeoutId);
}
这招在弱网环境下很实用,用户点取消、切页面、重复提交时,同样可以通过abort来避免多余的响应覆盖界面。
js 向服务器发送post请求时的常见坑与解决
POST请求相比GET,更容易因为格式问题被后端打回,整理几个高频坑位。
跨域请求被拦截
前端页面在a.com,接口在b.com,浏览器会拦截跨域请求,解决办法是让服务端返回CORS响应头,允许前端来源访问,前端在fetch里可以显式写:
fetch('https://b.com/api/data', {
method: 'POST',
credentials: 'include',
mode: 'cors'
});
注意credentials: include表示跨域时携带凭证,同时服务端Access-Control-Allow-Origin不能写星号,必须指定具体来源。
Content-Type写错导致数据到不了后端
- 发JSON字符串:Content-Type必须是application/json。
- 发查询字符串:Content-Type通常是application/x-www-form-urlencoded。
- 发FormData:不要手动设Content-Type,浏览器会生成带boundary的完整头。
GET请求传了request body导致报错
有一些后端框架,如Spring的某些版本,会直接忽略GET请求附带body,正确的做法是把参数拼到URL上,或者改用POST。
端口与本地代理的坑
开发环境下前后端端口不同,直连接口会撞上CORS,常见的处理方式是配置webpack devServer的proxy,或者用vite的server.proxy把/api前缀转发到后端服务,这样前端请求看起来是同源的。
关于js请求服务器数据的常见问题
js发送请求时怎么处理跨域?
优先让后端加上CORS相关响应头,如果只是开发阶段,用构建工具的代理转发更省事,JSONP这种老办法只适配GET接口,而且需要服务端配合包一层callback,现在很少用了。
用fetch发送post请求时content-type应该设成什么?
取决于发送的payload类型,JSON对象用application/json,URL编码表单用application/x-www-form-urlencoded,FormData对象不用手动指定,浏览器自动处理。
fetch和axios怎么选?
axios是对XMLHttpRequest的封装,支持请求拦截器、取消请求、自动转换JSON,fetch是浏览器原生能力,不用引包,轻量直接,如果你只在两三个页面发少量请求,fetch完全够用,如果项目里全局接口较多,需要统一管理拦截器、错误码、token注入,axios这类封装库更顺手。
说到底,js向服务器发送请求数据就是fetch和XMLHttpRequest两种工具,新代码优先fetch,出现特殊需求再回到XHR,把请求格式写对、状态码判断好、跨域配置对,数据交互就不会出大乱子。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/772720.html


