Axios 请求可以被取消吗?解析 Axios 请求取消机制
你大概率遇到过这些 UI 问题:搜索框打字太快,结果列表一会儿跳来跳去;路由切换后,上个页面的请求回来了把状态又写了一遍;或者用户连点两次提交,后端被打了两次还把前端状态搞乱。 这些问题背后的共同点就是:旧请求不该再影响当前界面。最直接的处理方式就是取消它(或者至少忽略它的结果)。下面按 Axios 的两套方案讲清楚怎么做,再给一些更贴近业务的封装写法。 技术实现方案对比1. 传统 CancelToken 方案适用版本: Axios < 0.22实现原理: Axios 自己的一套取消令牌(CancelToken),本质是通过 token 把“取消信号”传进请求链路里。 1234567891011121314// 创建令牌源const source = axios.CancelToken.source()// 发送请求axios.get('/api', { cancelToken: source.token}).catch(err => { if (axios.isCancel(err)) { c...
Cookie 能实现不同域共享吗?
这个问题在做 SSO、做多站点业务、或者“主站 + 独立活动页”时经常冒出来:A 域登录了,B 域能不能直接读到 A 的 Cookie? 结论先放前面:不同主域(不同 eTLD+1)之间,浏览器不允许你直接共享 Cookie。能做的只有“换个思路实现同样的业务目的”,比如跳转换票据、统一登录中心、或者用后端做代理。 Cookie 与同源策略同源策略是浏览器的基本安全机制,其核心要求是:只有当请求的协议、域名和端口号完全一致时,才视为同源。 对于 Cookie 来说,同源策略意味着默认情况下,Cookie 仅能在设定该 Cookie 的域名及其子域名中访问。 例如,设置 Cookie 时指定 Domain=.example.com 后,example.com 及其所有子域(如 sub1.example.com、sub2.example.com)都可以共享该 Cookie。但对于完全不同的主域,如 example.com 与 anotherdomain.com,浏览器会严格阻止 Cookie 共享。 由于同源策略的限制,直接实现不同主域之间(例如 example.com 与 ...
浅析微前端中的隔离策略
微前端这套东西,最真实的价值是“多个团队/多个技术栈能在一个壳里各自发版”。但它的副作用也很明显:大家都跑在同一个 window 里,谁动了全局变量、谁加了个不小心的样式、谁忘了清理定时器,别的应用可能就跟着倒霉。 所以隔离几乎是微前端绕不过去的一关。这篇文章想把三个问题讲清楚: 为什么很多团队不把 iframe 当成默认方案? 不用 iframe 的话,JS 隔离一般怎么做? qiankun 的沙箱、样式隔离大概是什么思路? 为什么需要 JavaScript 隔离?在微前端架构中,各个子应用通常由不同团队开发,它们可能使用不同的技术栈、框架甚至版本。当多个子应用运行在同一个全局环境中时,会产生以下问题: 全局变量污染:子应用可能会修改全局变量或挂载全局方法,导致其他子应用发生异常。 事件和定时器难清理:全局事件监听、定时器如果不卸载,切应用几次就会叠加成“幽灵回调”。 样式冲突:这不是 JS 隔离本身,但实际项目里几乎总会一起踩(全局选择器、reset、变量名撞车)。 为了避免这些问题,你得想办法把“子应用对全局的影响”控制住:要么给它一个独立运行环境(i...
如何标准化处理线上用户反馈的问题
线上用户反馈其实就是“线上报 bug”,只不过报的人可能不是研发:信息往往不全、描述也不一定准确。处理得好,团队能快速复现并修掉问题;处理得不好,就会陷入反复追问、反复转发、最后不了了之。 下面这套流程的目标很明确:每条反馈都能落到一个工单上,有人负责、有进度可查、最后能回到用户那里完成闭环。 建立统一的反馈系统多渠道入口整合第一步不是“上一个系统”,而是先把入口收拢:官网、App 内、社群、客服、邮箱……最后最好都能汇总到同一个地方(哪怕先从飞书表单/企业微信/简单工单开始)。入口分散的后果就是:反馈容易丢、重复登记、也很难统计。 自动化采集与手动补充能自动采集的字段尽量自动采集(系统版本、浏览器、页面 URL、设备信息、用户 ID/匿名 ID、时间戳),剩下的再让人工补齐。强烈建议对“必须字段”做约束,比如: 复现步骤(最重要) 期望结果 vs 实际结果 截图/录屏(能让沟通少一半) 日志/错误码(如果有的话) 每条反馈最好都有唯一编号(工单号),后面讨论就围绕这个号说话,避免“那个用户说的那个问题”这种对不上号的沟通...
package.json 里的 sideEffects 到底是干嘛的?
你第一次在 package.json 里看到 sideEffects,大概率是在某个组件库/工具库里: 1234{ "name": "some-lib", "sideEffects": false} 然后心里冒出一个很真实的问题:这玩意儿跟“副作用”到底有什么关系?我业务代码也没写 Redux 啊。 其实它就是在跟打包工具(最典型是 webpack)打招呼:“兄弟,我这里哪些模块导入时不会做额外事情,你可以放心 Tree Shaking;哪些模块导入时会偷偷改世界观,你别把它摇没了。” 先搞清楚:这里说的副作用是什么?在 sideEffects 语境里,“副作用”指的是:模块在被 import 的那一刻,就会发生一些“跟导出值无关”的行为。 最常见的副作用长这样: import 一个 CSS 文件(它不导出啥,但会影响样式) import 一个 polyfill(它会改全局对象/原型) import 一个初始化脚本(它会注册全局事件、往 window 挂东西、打点、改运行时...
如何解决页面请求接口大规模并发问题
真实项目里,“页面并发请求太多”一般不是压测才发现的,而是用户直接告诉你:打开页面慢、偶尔转圈、还会莫名其妙报错。 常见的触发方式也很朴素:一个页面初始化要拉权限、菜单、用户信息、配置、列表、筛选项、推荐位、埋点……再加上组件各自 useEffect 一起跑,瞬间就把并发拉满。 处理这类问题别只想着“后端扛一下”。更健康的做法是前后端一起把请求治理起来:前端负责减少/合并/排队/缓存,后端负责限流/排队/缓存/抗压。 前端层面优化1. 请求去重在某些情况下,页面可能会多次触发相同的请求,如用户快速点击按钮、页面轮询等。可以通过 请求去重 来避免无意义的重复请求。 实现方式 使用 Map 或 Set 记录正在进行的请求,并在请求完成后移除。 12345678910111213const pendingRequests = new Map<string, Promise<Response>>();async function fetchData(url: string, options: Reques...
如何保证用户的使用体验?
我一直觉得“用户体验”这个词很容易被说空:大家都同意体验重要,但落到具体需求上,经常又变成“加个动效”“换个配色”。 如果你把自己代入成用户,体验其实很直白: 我点了,有没有反应? 我等了,要等多久? 出错了,我能不能继续用? 我看到了,我是不是看得懂? 下面我按比较工程化的顺序,把前端侧常见的体验点拆开说。你可以当成一份自检清单:每次做页面/做功能,扫一遍基本不会差。 性能优化1. 加快页面加载速度 资源压缩与合并压缩 JavaScript、CSS 和图片资源,利用 webpack、Rollup 等打包工具进行代码分割(Code Splitting)和 Tree Shaking,减少不必要的资源加载。 CDN 加速使用 CDN 部署静态资源,使用户在不同地区均能快速加载页面内容。 缓存策略配置 HTTP 缓存、Service Worker 等机制,让用户在短时间内重复访问时无需重新加载所有资源。 2. 优化渲染与交互 异步加载利用懒加载和按需加载技术,仅在用户需要时加载相关模块,减少首屏加载时间。 减少重绘和重排尽量减少 DOM 操作,采用虚拟 DOM ...
不使用组件如何实现折叠面板效果
在 Web 开发中,折叠面板(Accordion)是一种常见的交互组件,用于在有限的空间内展示和隐藏内容。很多时候,我们希望自己手动实现这一效果,而不是依赖第三方组件库。 这里我分享两种实现方式:一种是直接用 HTML5 的 <details> / <summary>(省心、语义也好),另一种是用原生 HTML/CSS/JS 自己写一套(自由度更高)。 方法一:使用 <details> 和 <summary> 标签HTML5 提供了 <details> 和 <summary> 标签,原生支持折叠和展开的交互功能,非常简单且无需 JavaScript。通过添加适当的 CSS 样式,我们还可以对其进行美化和自定义。 我个人很喜欢这个方案:它自带交互和可访问性语义(键盘、屏幕阅读器基本都能友好工作)。很多“只是想折叠一下内容”的场景,用它比自己写 JS 更省心。 基本实现1234<details> <summary>面板标题</summary>...
如何做应用的灰度发布?
什么是灰度发布?上线最怕两件事:问题来得又快又猛,以及 你不知道到底是哪儿出了问题。 灰度发布(Canary/Gray Release)做的事情其实很简单:新版本先别全量,把它先丢进一小撮真实流量里跑一跑;指标正常就继续放量;指标不对就立刻停/回滚。它不是为了“更酷的发布姿势”,而是为了让你上线时更有底。 灰度发布的核心原理灰度发布的目标是降低风险,主要包括以下几个方面: 逐步推进:新版本先在小范围内上线,确保在大规模流量前验证稳定性。 监控与反馈:实时监控新版本的关键指标(例如错误率、响应时间、用户行为等),快速发现异常。 快速回滚:如果新版本出现问题,可以迅速切换回旧版本,减少用户受到的影响。 用户分组:通过用户标识(例如 IP、地理位置、用户等级等)或随机抽样,将用户分为不同的组别,以实现流量切分。 实现灰度发布的常用策略1. 使用特性开关(Feature Flags)特性开关允许你在代码层面控制新功能的启用或关闭。常见实现方式包括: 在代码中通过环境变量或配置文件判断是否启用新功能。 将新功能的代码逻辑包裹在条件语句中,仅对特定用户生效。 通过...
如何保证批量请求失败,只弹出一个 Toast
这个问题你一定见过:页面一进来打了十几个接口,其中好几个因为 401/500 挂了,然后 UI 像“放鞭炮”一样连弹十几个 Toast。 用户第一反应不是“哦有些接口失败了”,而是“这页面炸了”。所以更合理的体验是:短时间内同类错误合并提示,最多弹一次(或者合并成一个更清晰的提示)。 实现思路 维护一个全局状态,用于记录是否已经弹出 Toast。 使用节流函数(throttle)或定时器,确保短时间内多个请求失败时,仅触发一次 Toast。 支持批量请求的全局错误拦截,如拦截 Axios 的响应错误,或者在 Fetch API 中封装统一的错误处理。 具体实现1. 使用全局状态记录 Toast123456789101112131415161718192021222324252627282930313233343536373839import axios from "axios";import { message } from "antd";// 定义一个全局状态,记录是否已经显示 Toastlet toa...
