04 - JS Web API
目录
一、JS Web API 概览
- JS 基础:ECMA 262 标准
- JS Web API:网页操作相关 API,W3C 标准
| API 类别 | 说明 | 常用接口 |
|---|---|---|
| DOM API | 操作 HTML/XML 文档结构 | document.querySelector、addEventListener |
| BOM API | 与浏览器窗口和环境交互 | window、location、history、navigator |
| 网络请求 API | 发送 HTTP 请求 | fetch、XMLHttpRequest |
| 存储 API | 客户端数据存储 | localStorage、sessionStorage、IndexedDB |
| 实时通信 API | 双向数据流 | WebSocket、WebRTC、getUserMedia |
二、DOM 操作
DOM 本质
HTML 是特定的 XML,DOM 是浏览器内存中保存的多叉树(n-ary tree),由 HTML + CSS + JS 共同生成。
获取 DOM 节点
js
document.getElementById('d1')
document.getElementsByTagName('div') // HTMLCollection(动态)
document.getElementsByClassName('container') // HTMLCollection(动态)
document.querySelector('div') // 单个元素
document.querySelectorAll('div') // NodeList(静态)getElementById vs querySelector 对比
| 特性 | getElementById | querySelector |
|---|---|---|
| 参数 | 只接受 id 字符串(无需 #) | 接受任意 CSS 选择器 |
| 返回值 | 单个元素 | 第一个匹配元素 |
| 性能 | 较快(专门 id 优化) | 略慢(需解析选择器) |
| 调用范围 | 只能在 document 上 | document 和任意 DOM 元素 |
HTMLCollection vs NodeList
| 特性 | HTMLCollection | NodeList |
|---|---|---|
| 来源 | getElementsBy* 系列 | querySelectorAll |
| 是否实时 | ✅ 动态(DOM 变化自动同步) | ❌ 静态快照 |
| 转数组 | Array.from(collection) | [...nodeList] 或 Array.from() |
attribute 与 property
| 特性 | attribute | property |
|---|---|---|
| 来源 | HTML 标签中定义的属性 | DOM 对象的 JavaScript 属性 |
| 访问方式 | getAttribute()、setAttribute() | el.style.width、el.className 等 |
| 是否影响 HTML 结构 | ✅ 一定会修改 | ❌ 不一定 |
| 是否引起重新渲染 | 可能 | 可能 |
js
// attribute 操作
p.getAttribute('data-name');
p.setAttribute('data-name', 'value');
// property 操作
p.style.width = '100px';
p.className = 'active';增/删/移动节点

js
// 新建节点
const newDiv = document.createElement('div');
newDiv.textContent = '新内容';
// 插入节点
parent.appendChild(newDiv);
parent.insertBefore(newDiv, referenceNode);
// 移动节点(将已有节点移到新位置)
const existingNode = document.getElementById('exist');
parent.appendChild(existingNode); // 自动从原位置移走
// 删除节点
parent.removeChild(child);


通过
node.parentNode获取父元素节点
通过node.childNodes获取子节点(包括文本节点 nodeType=3、注释节点 nodeType=8)
DOM 常用 API 速查
| 方法/属性 | 功能 |
|---|---|
getElementById() | 根据 id 获取单个元素 |
getElementsByClassName() | 获取指定类名的元素集合 |
getElementsByTagName() | 根据标签名获取集合 |
querySelector() | CSS 选择器获取第一个匹配元素 |
querySelectorAll() | CSS 选择器获取所有匹配元素 |
createElement() | 创建新元素节点 |
appendChild() | 在父节点末尾追加子节点 |
insertBefore() | 在指定节点前插入新节点 |
removeChild() | 删除子节点 |
replaceChild() | 替换子节点 |
cloneNode(true) | 深克隆节点 |
hasOwnProperty() | 判断是否为自身属性 |
parentNode | 获取父节点 |
childNodes | 获取所有子节点 |
nextElementSibling | 下一个兄弟元素节点 |
previousElementSibling | 上一个兄弟元素节点 |
DOM 性能优化
- 对 DOM 查询结果做缓存(避免重复查询)
- 将频繁操作改为一次性操作(使用
DocumentFragment) - 批量插入时先构建
DocumentFragment,再一次性插入

js
// 使用 DocumentFragment 批量插入
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
fragment.appendChild(li);
}
document.getElementById('list').appendChild(fragment); // 一次性插入DOM 性能优化要点
| 优化点 | 说明 |
|---|---|
| 减少重排/重绘 | 重排(修改布局属性)比重绘(仅外观变化)代价更高 |
| 批量操作 | 用 DocumentFragment 或 innerHTML 批量更新 |
| 使用 CSS 类 | 用 classList.add/remove 替代直接操作 style |
| 事件委托 | 将子元素事件委托到父元素,减少事件监听数量 |
| 虚拟 DOM | React/Vue 使用 vDOM + diff 算法批量更新 |
| requestAnimationFrame | 将复杂动画/批量操作放到 rAF 回调中 |
三、BOM 常用对象
| 对象 | 说明 |
|---|---|
window | 全局对象,浏览器窗口 |
navigator | 浏览器信息(userAgent、语言等) |
location | 当前 URL 操作(href、reload()、search、hash) |
history | 浏览器历史(back()、forward()、pushState()) |
screen | 屏幕尺寸信息 |
四、网络请求:Ajax / Fetch
手写 Ajax(XMLHttpRequest)
js
function ajax(url, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true); // true = 异步
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(xhr.response);
} else {
console.error(`获取失败: ${xhr.status}`);
}
}
};
xhr.send(null); // GET 请求不需要 body
}
readyState 状态值
| 值 | 含义 |
|---|---|
| 0 | 未初始化 |
| 1 | 已调用 open() |
| 2 | 已调用 send() |
| 3 | 接收数据中 |
| 4 | 完成(可以处理响应) |
Ajax vs Fetch vs Axios
| 特性 | XMLHttpRequest | Fetch | Axios |
|---|---|---|---|
| 语法 | 回调式 | Promise | Promise |
| 错误处理 | 通过状态码判断 | 只有网络错误才 reject | 自动处理 HTTP 错误 |
| 请求取消 | xhr.abort() | AbortController | CancelToken |
| 拦截器 | 无 | 无 | ✅ 有 |
| 默认 JSON | 需手动解析 | 需手动 .json() | ✅ 自动 |
五、跨域
同源策略
同源:协议 + 域名 + 端口 三者完全一致。
AJAX 受同源策略限制,但 <img>、<link>、<script> 可以无视同源策略。
<img>标签加载跨域图片时,可用于统计打点(携带参数的图片 GET 请求,无 CORS 限制)。
解决跨域的方式
1. JSONP(仅限 GET)
原理:利用 <script> 标签可跨域的特性,服务器动态返回 JS 代码(调用约定好的回调函数)。
js
// 前端
function callback(data) {
console.log('JSONP 数据:', data);
}
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=callback';
document.head.appendChild(script);
2. CORS(服务器端配置)
服务器通过 HTTP 响应头告知浏览器是否允许跨域:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
所有跨域,都需要经过服务端的允许与配合。
六、浏览器存储
三种存储方式对比
| 特性 | Cookie | localStorage | sessionStorage |
|---|---|---|---|
| 存储容量 | 4KB | 5~10MB | 5~10MB |
| 生命周期 | 可设置过期时间 | 永久(需手动清除) | 会话级(标签页关闭即清除) |
| 数据作用域 | 同域名下所有页面 | 同域名下所有页面 | 同域名且同标签页 |
| HTTP 请求自动携带 | ✅ 是 | ❌ 否 | ❌ 否 |
| 访问权限 | 前端 + 后端 | 仅前端 | 仅前端 |
| 存储格式 | 字符串键值对 | 字符串键值对(需 JSON) | 字符串键值对(需 JSON) |
| 安全性 | 可设置 HttpOnly、Secure、SameSite | 明文,需防 XSS | 明文,需防 XSS |
Cookie 特点与限制
- 大小限制 4KB
- 每次 HTTP 请求都会携带到服务端(增加请求数据量)
- 重要安全属性:
HttpOnly:禁止 JS 访问,防止 XSSSecure:只在 HTTPS 下发送SameSite:防 CSRF 攻击
js
// 前端 JS 读写 Cookie
document.cookie = 'a=100; path=/; expires=Mon, 01 Jan 2026 00:00:00 GMT';localStorage / sessionStorage API
js
localStorage.setItem('key', JSON.stringify({ a: 1 }));
const data = JSON.parse(localStorage.getItem('key'));
localStorage.removeItem('key');
localStorage.clear();
sessionStorage.setItem('form', '草稿内容');
sessionStorage.getItem('form');