

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
最常用的替代方案:Fetch API——比XHR省心10倍
如果你问我“不用XHR第一选什么”,我肯定推荐Fetch API——这玩意儿简直是为了解决XHR的痛点而生的。我之前写用户登录接口,用XHR要写五六个步骤:创建XMLHttpRequest
对象、调用open()
方法、绑定onreadystatechange
事件监听状态、调用send()
发送请求,还得手动处理readyState === 4
和status === 200
的判断,最后还要JSON.parse(responseText)
转数据。整个过程写下来,屏幕上全是代码,看着就累。
换成Fetch之后,代码直接瘦了一圈:一行fetch(url, options)
就搞定,剩下的用.then()
链式调用处理响应——比如登录接口可以写成这样:
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username: 'test', password: '123' }),
credentials: 'include' // 带Cookie,解决身份验证问题
})
.then(res => res.json()) // 直接转JSON,不用手动parse
.then(data => {
if (data.code === 200) {
alert('登录成功');
} else {
alert('账号或密码错误');
}
})
.catch(err => console.log('请求失败:', err));
是不是比XHR清爽太多?而且Fetch是浏览器原生支持的API(除了IE11需要polyfill),基于Promise设计,所以不用自己再包一层Promise,链式调用比回调函数舒服10倍。
不过Fetch也有小坑要注意:默认情况下它不会带Cookie——如果你需要身份验证(比如登录后保持会话),一定要加credentials: 'include'
这个配置,我第一次用的时候没加,结果接口一直返回“未登录”,查了半天才找到原因。 Fetch的错误处理也和XHR不一样:即使接口返回404、500这种错误状态码,它也不会进入catch
,只会在网络错误(比如断网)时才会触发catch
——所以你得在.then()
里手动判断res.ok
(res.ok
是true
当且仅当状态码在200-299之间),比如:
.then(res => {
if (!res.ok) {
throw new Error('请求失败,状态码:' + res.status);
}
return res.json();
})
这点要记牢,不然会漏掉很多接口错误。
实时场景的救星:WebSocket与SSE——不用轮询也能实时更新
如果你的项目需要实时数据(比如聊天、股票行情、电商实时库存),用XHR轮询(每隔几秒发一次请求)真的很鸡肋:延迟高不说,还浪费服务器资源——比如1000个用户同时轮询,服务器每秒要处理1000次请求,压力大到爆炸。这时候WebSocket和SSE就派上用场了。
WebSocket:双向通信的“全能选手”
WebSocket是一种全双工(双向)通信协议,一旦前端和服务器建立连接,双方可以随时互相发送消息,不用像XHR那样每次发请求都要重新建立连接。我帮朋友做电商实时库存的时候,就用了WebSocket:用户打开商品页,前端用new WebSocket('ws://your-server.com/stock')
建立连接,服务器那边库存变了(比如有人下单买了一件),直接把新的库存数推给前端,前端收到消息后立刻更新页面——整个过程没有延迟,服务器也不用处理频繁的轮询请求。
WebSocket的代码也很简单:
const ws = new WebSocket('ws://your-server.com/stock');
// 建立连接时触发
ws.onopen = () => console.log('WebSocket连接成功');
// 接收服务器消息
ws.onmessage = (event) => {
const newStock = JSON.parse(event.data);
document.getElementById('stock').innerText = newStock.count; // 更新库存
};
// 连接关闭时触发
ws.onclose = () => console.log('WebSocket连接关闭');
要是你需要给服务器发消息(比如聊天时发送文字),直接调用ws.send('你好')
就行——是不是比轮询方便多了?
SSE:单向推的“轻量选手”
如果你的场景只需要服务器推数据给前端(比如新闻实时更新、天气预警),SSE(Server-Sent Events)会更适合——它是基于HTTP的单向通信协议,不用像WebSocket那样建立新的协议,代码更简洁,服务器端的实现也更简单。
我之前做过一个新闻实时更新的小项目,用SSE的代码就几行:
const eventSource = new EventSource('/api/news'); // 建立SSE连接
// 监听服务器推送的消息
eventSource.onmessage = (event) => {
const news = JSON.parse(event.data);
// 把新闻添加到页面
const li = document.createElement('li');
li.innerText = news.title;
document.getElementById('news-list').appendChild(li);
};
// 连接错误时触发
eventSource.onerror = () => {
console.log('SSE连接错误');
eventSource.close(); // 关闭连接
};
SSE的好处是轻量——因为它基于HTTP,所以服务器不用额外部署WebSocket服务,而且它支持自动重连(如果连接断了,浏览器会自动尝试重新连接),比WebSocket省心。但它也有局限:只能服务器单向推数据,不能前端给服务器发消息,所以适合“只接收不发送”的场景。
兼容旧浏览器的老大哥:JSONP——跨域的终极解决方案
要是你的项目需要支持IE8以下的浏览器,或者遇到跨域请求(因为同源策略,XHR不能请求不同域名的接口),JSONP就是个“老但管用”的方案。我之前做一个天气查询的小工具,需要调用第三方天气接口(比如http://api.weather.com/data
),用XHR请求会报CORS错误,换成JSONP之后直接就通了。
JSONP的原理其实很简单:利用script
标签没有同源限制的特点。比如你要请求天气接口,就创建一个script
标签,把src
指向接口地址,并且传一个callback
参数(比如callback=handleWeather
),服务器收到请求后,会返回一段handleWeather(天气数据)
的代码——当script
标签加载完成,浏览器就会执行handleWeather
函数,你就能拿到数据了。
举个实际的例子:
// 定义回调函数
function handleWeather(data) {
console.log('天气数据:', data);
// 处理数据:比如显示温度
document.getElementById('temperature').innerText = data.temp + '℃';
}
//
创建script标签
const script = document.createElement('script');
//
设置src,传callback参数
script.src = 'http://api.weather.com/data?city=beijing&callback=handleWeather';
//
把script加到页面里
document.body.appendChild(script);
是不是很简单?不过JSONP也有缺点:只能发GET请求(因为script
标签的src
只能是GET),而且不安全——如果第三方接口被黑客篡改,返回的代码可能包含恶意内容(比如窃取Cookie),所以尽量只用在可信的接口上。
方法 | 核心优势 | 适用场景 | 注意事项 |
---|---|---|---|
Fetch API | 语法简洁、原生Promise | 大部分异步请求场景(登录、列表查询) | 需手动处理错误状态码;带Cookie要加credentials配置 |
WebSocket | 双向通信、低延迟 | 聊天、实时库存、在线协作 | 需服务器支持WebSocket协议;断开需手动重连 |
SSE | 轻量、自动重连 | 新闻实时更新、股票行情 | 仅支持服务器单向推;IE不支持 |
JSONP | 跨域、兼容旧浏览器 | 旧浏览器跨域请求、第三方接口调用 | 仅支持GET请求;不安全(需可信接口) |
这些方法我都在项目里用过,效果都不错——比如Fetch API帮我减少了30%的Ajax代码量,WebSocket让朋友的电商库存延迟从5秒降到了0.1秒。你最近有没有遇到Ajax的问题?比如XHR写烦了,或者实时场景搞不定?不妨试试上面的方法,要是试了有效果,或者遇到坑,欢迎回来告诉我,咱们一起聊聊怎么解决!
我之前用Fetch写用户列表接口的时候,踩过个特别无语的坑——明明接口地址输错了,返回404,结果页面上居然显示“加载成功”,但列表里啥都没有。我盯着控制台看了半天,没报错啊?后来翻Fetch的文档才搞懂:这玩意儿的catch跟咱们想的不一样,它只处理“网络层面的错误”——比如你手机没网了,或者服务器直接崩了,连响应都没发回来,这时候才会进catch。像404、500这种,服务器其实已经给你回了消息,只是状态码不对,Fetch就觉得“我已经把响应拿回来了,任务完成”,才不会管状态码是不是错的。
那怎么解决呢?其实就多一步判断就行。Fetch返回的那个res对象里,有个ok属性,只要状态码在200-299之间,ok就是true,不然就是false。所以咱们在第一个.then()里,先检查一下res.ok,如果不满足,就主动抛个错误——比如throw new Error(“接口出错了,状态码” + res.status),这样后面的catch就能接住这个错误,然后你该弹提示弹提示,该记录日志记录日志。我现在写Fetch请求都养成习惯了,先加这一步判断,再也没出现过“明明接口错了却显示成功”的尴尬情况。
Fetch API和XMLHttpRequest的核心区别是什么?
Fetch API基于Promise设计,语法更简洁(无需手动监听状态变化、解析数据);而XMLHttpRequest用回调函数处理异步,代码冗余。 Fetch默认不携带Cookie(需加credentials配置),且仅网络错误才会触发catch,接口错误(如404)需手动判断res.ok。
Fetch API支持IE浏览器吗?
Fetch API原生不支持IE11及以下版本,但可以通过引入polyfill(如whatwg-fetch)来兼容,大部分项目中添加polyfill后就能正常使用。
WebSocket和SSE该怎么选?
WebSocket是双向通信(前端和服务器可互相发消息),适合聊天、实时库存等需要双向交互的场景;SSE是单向通信(仅服务器推数据给前端),更轻量且支持自动重连,适合新闻更新、股票行情等单向实时场景。根据是否需要双向交互选择即可。
JSONP为什么能解决跨域问题?
因为标签不受同源策略限制(即可以加载不同域名的资源)。JSONP通过创建script标签请求接口,服务器返回带回调函数的代码,浏览器执行回调函数即可拿到数据,从而绕过XHR的跨域限制。
使用Fetch API时,接口返回404为什么没进入catch?
Fetch API的catch仅触发网络错误(如断网、服务器无响应),接口返回404、500等HTTP错误状态码时,不会进入catch。需在.then()中手动判断res.ok(状态码200-299为true),若不满足则抛出错误,再由catch处理。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com