深入理解Ajax核心机制与实战技巧
1. 从零理解Ajax的核心机制2005年Jesse James Garrett首次提出Asynchronous JavaScript and XML这个术语时可能没想到它会成为现代Web开发的基石。我在2010年第一次接触Ajax时被它无需刷新页面就能更新内容的能力震撼——这彻底改变了用户与网页交互的方式。Ajax本质上是一组技术的组合应用XMLHttpRequest对象浏览器与服务器通信的桥梁JavaScript/DOM动态更新页面内容CSS改变界面样式数据格式早期多用XML现在JSON已成主流关键认知Ajax不是新技术而是现有技术的创新应用方式。就像用乐高积木搭建航天飞机——材料是旧的组合方式是革命性的。2. 原生Ajax实现全流程拆解2.1 创建XHR对象的正确姿势// 兼容IE6的创建方式现在已无需考虑 function createXHR() { if (typeof XMLHttpRequest ! undefined) { return new XMLHttpRequest(); } else if (typeof ActiveXObject ! undefined) { return new ActiveXObject(Microsoft.XMLHTTP); } throw new Error(No XHR object available); } // 现代浏览器只需一行 const xhr new XMLHttpRequest();我在2015年维护一个老旧系统时曾因忘记处理IE兼容性导致页面崩溃。虽然现在不需要考虑ActiveXObject但了解这段历史有助于理解Web技术的发展脉络。2.2 请求配置的魔鬼细节xhr.open(POST, /api/data, true); // 第三个参数决定异步与否 xhr.setRequestHeader(Content-Type, application/json); xhr.timeout 3000; // 3秒超时容易踩的坑忘记设置Content-Type导致后端无法解析数据同步请求false会阻塞页面——我在2018年因此导致移动端用户投诉跨域请求需要服务端配合CORS配置2.3 发送请求的参数处理艺术// GET请求参数处理 function paramsToQuery(params) { return Object.keys(params).map(k ${encodeURIComponent(k)}${encodeURIComponent(params[k])} ).join(); } const query paramsToQuery({ page: 1, size: 20 }); xhr.open(GET, /api/list?${query}, true); xhr.send(); // POST JSON数据 xhr.send(JSON.stringify({ username: test, pwd: 123456 }));安全提示永远不要直接拼接参数到URL中2016年某电商网站就因未编码参数导致XSS漏洞2.4 响应处理的完整生命周期xhr.onreadystatechange function() { if (xhr.readyState 4) { if (xhr.status 200) { try { const data JSON.parse(xhr.responseText); // 处理数据... } catch(e) { console.error(JSON解析失败, e); } } else { handleError(xhr.status, xhr.statusText); } } }; // 更现代的写法 xhr.onload function() { if (xhr.status 200 xhr.status 300) { // 成功处理 } else { // 错误处理 } }; xhr.onerror function() { // 网络错误处理 }; xhr.ontimeout function() { // 超时处理 };状态码处理经验2xx成功但204 No Content需要特殊处理3xx通常浏览器会自动处理重定向4xx客户端错误401要跳登录403提示权限不足5xx服务端错误建议友好提示并记录日志3. 实战中的高阶技巧3.1 取消请求的两种方案// 方案1abort方法 const xhr new XMLHttpRequest(); xhr.open(GET, /api/large-data, true); xhr.send(); // 用户离开页面时取消 window.addEventListener(beforeunload, () { xhr.abort(); }); // 方案2可取消的Promise包装 function cancellableXHR(config) { const xhr new XMLHttpRequest(); const promise new Promise((resolve, reject) { xhr.open(config.method || GET, config.url, true); Object.keys(config.headers || {}).forEach(key { xhr.setRequestHeader(key, config.headers[key]); }); xhr.onload () resolve(JSON.parse(xhr.responseText)); xhr.onerror () reject(new Error(Request failed)); xhr.ontimeout () reject(new Error(Request timeout)); xhr.send(config.data); }); return { promise, cancel: () xhr.abort() }; }3.2 文件上传进度监控const xhr new XMLHttpRequest(); const fileInput document.getElementById(avatar); xhr.upload.onprogress function(e) { if (e.lengthComputable) { const percent Math.round((e.loaded / e.total) * 100); progressBar.style.width ${percent}%; } }; fileInput.addEventListener(change, function() { const formData new FormData(); formData.append(avatar, this.files[0]); xhr.open(POST, /upload, true); xhr.send(formData); });性能优化点大文件分片上传压缩后再上传断点续传实现4. 常见问题排查指南4.1 跨域问题全解// 服务端需要设置的响应头 Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Content-Type // 前端预检请求处理 xhr.open(PUT, https://api.example.com/data, true); xhr.setRequestHeader(X-Custom-Header, value);跨域解决方案对比CORS推荐JSONP仅限GET代理服务器开发环境常用postMessageiframe通信4.2 调试技巧集合// 查看所有请求头 xhr.addEventListener(load, function() { console.log(this.getAllResponseHeaders()); }); // 性能分析 console.time(ajax-request); xhr.onload function() { console.timeEnd(ajax-request); };Chrome调试技巧网络面板的XHR筛选右键请求 - Copy - Copy as cURL禁用缓存Disable cache选项5. 现代替代方案5.1 Fetch API对比// 基本使用 fetch(/api/data) .then(response { if (!response.ok) throw new Error(Network error); return response.json(); }) .then(data console.log(data)) .catch(error console.error(error)); // 带配置的POST请求 fetch(/api/save, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ title: New Post }) });XHR vs FetchFetch更简洁但XHR支持进度监控Fetch错误处理更复杂不会reject HTTP错误状态Fetch默认不带cookie需要配置credentials5.2 Axios实战技巧// 拦截器配置 axios.interceptors.request.use(config { config.headers.Authorization localStorage.getItem(token); return config; }); // 并发请求 Promise.all([ axios.get(/api/user), axios.get(/api/posts) ]).then(([user, posts]) { // 处理数据 });Axios优势请求/响应拦截器自动转换JSON数据客户端XSRF防护取消请求支持6. 性能优化实战6.1 请求合并策略// 批量获取用户信息 function getUsers(ids) { return axios.post(/api/users/batch, { ids }); } // 代替循环中的单个请求 const userIds [1, 2, 3, 4]; getUsers(userIds).then(users { // 处理用户列表 });6.2 缓存实现方案const apiCache new Map(); function cachedRequest(url) { if (apiCache.has(url)) { return Promise.resolve(apiCache.get(url)); } return axios.get(url) .then(response { apiCache.set(url, response.data); return response.data; }); }缓存策略选择内存缓存短期localStorage长期Service Worker离线可用7. 安全防护要点7.1 CSRF防护// 自动从cookie读取token axios.defaults.xsrfCookieName csrftoken; axios.defaults.xsrfHeaderName X-CSRFToken; // 手动添加 const csrfToken document.querySelector(meta[namecsrf-token]).content; axios.post(/api/sensitive, data, { headers: { X-CSRFToken: csrfToken } });7.2 输入验证function sanitizeInput(input) { return input.replace(//g, lt;).replace(//g, gt;); } axios.post(/api/comment, { content: sanitizeInput(userInput) });必须防御的攻击类型XSS跨站脚本SQL注入JSON劫持点击劫持

相关新闻

Jupyter Notebook:Python数据科学交互式开发指南

Jupyter Notebook:Python数据科学交互式开发指南

1. Jupyter Notebook:Python开发者的交互式利器第一次接触Jupyter Notebook是在2016年的一个数据分析项目上。当时我需要频繁地测试数据清洗代码片段,传统IDE的"编辑-运行-调试"循环让我效率低下。直到同事推荐了这个能直接在浏览器里写Python…

2026/10/19 12:14:39 阅读更多 →
MySQL与Redis在数据收集系统中的优化实践

MySQL与Redis在数据收集系统中的优化实践

1. 项目概述"2024-12-08-2-收集"这个看似简单的标题背后,实际上隐藏着一个典型的数据收集与分析项目。作为一名长期与数据库打交道的开发者,我见过太多类似的项目命名方式——用日期和序号来标记数据收集批次。这种命名虽然简单直接&#xff0…

2026/10/19 13:02:47 阅读更多 →
从 Demo 顺滑到生产崩溃:引入 Hermes 后,我为什么先砍掉了自动重试逻辑?

从 Demo 顺滑到生产崩溃:引入 Hermes 后,我为什么先砍掉了自动重试逻辑?

如果你正准备往大模型方向转,《Hermes真能提效吗?先看流程里最慢的那一步》这类问题别只看热度。更重要的是判断自己该补哪块能力,以及怎么证明你真的会。摘要先把这篇文章的目标说清楚:看完之后,你应该能判断这件事值…

2026/10/19 13:01:27 阅读更多 →

最新新闻

多智能体协作框架选型指南:AgentScope标准化消息机制与工程实践

多智能体协作框架选型指南:AgentScope标准化消息机制与工程实践

最近半年我几乎把市面上能试的多智能体开发框架都试了一遍,要么太重,一上来就是企业级流程引擎、状态机、沙箱,光是理解抽象概念就得花一周;要么太薄,本质就是把大模型API包装成函数,智能体之间怎么通信、上…

2026/10/20 12:08:03 阅读更多 →
单相交流电子负载的核心:DQ锁相环与SOGI在STM32上的实现

单相交流电子负载的核心:DQ锁相环与SOGI在STM32上的实现

简介:面向2022年电赛A题“单相交流电子负载”的STM32F407VET6单相DQ锁相环工程,针对PWM整流与逆变器场景下的电网同步难题,提供从三相DQ锁相原理迁移到单相的完整实现思路,适用于电赛备赛学生与电力电子方向开发者参考。压缩包共1…

2026/10/20 12:08:03 阅读更多 →
国产算力地基开源:大模型推理从能跑到跑得好的底层优化实践

国产算力地基开源:大模型推理从能跑到跑得好的底层优化实践

1. 从"模型狂欢"到"地基焦虑":为什么这次开源值得单独聊过去两年,大家习惯了每隔几周就有一个新模型刷榜,参数从百亿卷到千亿,上下文从 32K 卷到 1M,评测分数一轮比一轮好看。但真正在一线做推理部…

2026/10/20 12:08:03 阅读更多 →
单相交流电子负载核心技术:PWM整流与DQ锁相环实现解析

单相交流电子负载核心技术:PWM整流与DQ锁相环实现解析

简介:面向2022年电赛A题参赛者,围绕单相交流电子负载与单相PWM整流器中的电网同步需求,给出基于STM32F407VET6的单相DQ锁相环工程实现。工程由STM32CubeMX生成初始化代码,核心算法参考三相DQ锁相原理改写,主要程序集中…

2026/10/20 12:08:03 阅读更多 →
STC15W4K软件库移植指南:寄存器、串口与ADC外设驱动实战

STC15W4K软件库移植指南:寄存器、串口与ADC外设驱动实战

简介:面向STC15W4K系列单片机的嵌入式开发,这套软件库将I/O端口操作、定时器配置、串口通信、中断处理、ADC转换等常用功能封装为可直接调用的函数,帮助开发者减少重复开发底层驱动的工作,专心实现业务逻辑。借助这些封装好的模块…

2026/10/20 12:08:03 阅读更多 →
IDEA中将JNI DLL打包进JAR的完整实践指南

IDEA中将JNI DLL打包进JAR的完整实践指南

1. 项目概述:为什么要把 JNI DLL 打进 JAR 包里?“idea jni dll打包进jar”——这短短九个字,背后藏着 Java 工程师在跨平台调用本地代码时最真实、最频繁的痛点。我第一次遇到这个问题,是在给某高校实验室开发一个图像预处理模块…

2026/10/20 12:07:02 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →