XMLHttpRequest 事件驱动、可中断、默认携 Cookie;fetch 基于 Promise、需显式配置 credentials 和 redirect;常见错误包括 fetch 不自动重定向、XHR 未校验 readyState 和 status。

浏览器发起 AJAX 请求时,XMLHttpRequest 和 fetch 的行为差异
现代前端发动态请求,基本绕不开 XMLHttpRequest(XHR)和 fetch。它们都走 HTTP 协议栈,但底层处理逻辑不同:XHR 是事件驱动、可中断、支持上传进度;fetch 基于 Promise、默认不带 Cookie、无法原生取消(需靠 AbortController)。比如发一个带登录态的请求,fetch 必须显式加 credentials: 'include',而 XHR 默认会携带同域 Cookie。
常见错误现象:
-
fetch返回 200 但响应体为空 —— 实际是服务端返回了重定向(302),fetch默认不跟随,需设redirect: 'follow' - XHR 在
onload中取不到responseText—— 忘了检查readyState === 4 && status === 200
后端返回 JSON 时,前端解析失败的典型原因
服务端返回 Content-Type: application/json 是理想状态,但现实中常有偏差。比如 Flask 默认返回 text/html,Django 在调试模式下可能返回 HTML 错误页而非 JSON;Node.js 的 Express 若没调 res.json() 而用 res.send({}),也可能漏设头。
实际排查建议:
- 先看浏览器 Network 面板里 Response Headers 的
Content-Type值是否为application/json - 如果返回的是字符串(如
"{...}"),JSON.parse()会成功;但如果返回的是 HTML(如 500 错误页),JSON.parse()直接抛SyntaxError - 用
response.clone().text()检查原始响应体内容,比盲目.json()更可靠
服务端如何正确设置 CORS 头以支持前端跨域请求
CORS 不是前端能单方面解决的问题。关键 Header 是 Access-Control-Allow-Origin,但它必须和服务端的其他策略配合才有效。比如前端带凭证(Cookie 或 Authorization)时,服务端必须同时设 Access-Control-Allow-Credentials: true,且 Access-Control-Allow-Origin 不能为 *,必须写明确域名(如 https://example.com)。
容易踩的坑:
- Nginx 反向代理时只加了
add_header Access-Control-Allow-Origin "*",但没处理预检请求(OPTIONS)—— 导致带自定义 Header 的请求直接 403 - Spring Boot 用
@CrossOrigin注解,但 Controller 方法参数用了@RequestBody,却没配Content-Type: application/json,触发预检失败 - Tomcat 的
web.xml配 filter 时,filter 顺序错位,导致 CORS 头被后续 filter 覆盖
动态内容渲染后,DOM 更新时机与事件绑定失效问题
拿到 API 数据并插入 HTML 后,新节点上的事件监听器不会自动继承。比如用 innerHTML 插入带 button 的片段,再对所有 .btn 调 addEventListener,只会绑定到插入前已存在的元素。
可行解法:
- 插入后立即遍历新节点,手动绑定事件(适合少量、结构固定的场景)
- 用事件委托:在父容器上监听,用
event.target.matches('.dynamic-btn')判断来源(推荐,性能好、无需关心插入时机) - 避免直接操作
innerHTML,改用document.createElement+appendChild,便于统一管理生命周期
注意:若插入内容含 <script></script> 标签,原生 DOM 方法(如 innerHTML)不会执行其中 JS;eval 或动态创建 script 元素才能运行,但有安全风险,不建议。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











