Skip to content

04 - JS Web API

目录


一、JS Web API 概览

  • JS 基础:ECMA 262 标准
  • JS Web API:网页操作相关 API,W3C 标准
API 类别说明常用接口
DOM API操作 HTML/XML 文档结构document.querySelectoraddEventListener
BOM API与浏览器窗口和环境交互windowlocationhistorynavigator
网络请求 API发送 HTTP 请求fetchXMLHttpRequest
存储 API客户端数据存储localStoragesessionStorageIndexedDB
实时通信 API双向数据流WebSocketWebRTCgetUserMedia

二、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 对比

特性getElementByIdquerySelector
参数只接受 id 字符串(无需 #接受任意 CSS 选择器
返回值单个元素第一个匹配元素
性能较快(专门 id 优化)略慢(需解析选择器)
调用范围只能在 documentdocument 和任意 DOM 元素

HTMLCollection vs NodeList

特性HTMLCollectionNodeList
来源getElementsBy* 系列querySelectorAll
是否实时✅ 动态(DOM 变化自动同步)❌ 静态快照
转数组Array.from(collection)[...nodeList]Array.from()

attribute 与 property

特性attributeproperty
来源HTML 标签中定义的属性DOM 对象的 JavaScript 属性
访问方式getAttribute()setAttribute()el.style.widthel.className
是否影响 HTML 结构✅ 一定会修改❌ 不一定
是否引起重新渲染可能可能
js
// attribute 操作
p.getAttribute('data-name');
p.setAttribute('data-name', 'value');

// property 操作
p.style.width = '100px';
p.className = 'active';

增/删/移动节点

DOM节点操作

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,再一次性插入

DOM批量操作优化

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 性能优化要点

优化点说明
减少重排/重绘重排(修改布局属性)比重绘(仅外观变化)代价更高
批量操作DocumentFragmentinnerHTML 批量更新
使用 CSS 类classList.add/remove 替代直接操作 style
事件委托将子元素事件委托到父元素,减少事件监听数量
虚拟 DOMReact/Vue 使用 vDOM + diff 算法批量更新
requestAnimationFrame将复杂动画/批量操作放到 rAF 回调中

三、BOM 常用对象

对象说明
window全局对象,浏览器窗口
navigator浏览器信息(userAgent、语言等)
location当前 URL 操作(hrefreload()searchhash
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
}

Ajax请求示意

readyState 状态值

含义
0未初始化
1已调用 open()
2已调用 send()
3接收数据中
4完成(可以处理响应)

Ajax vs Fetch vs Axios

特性XMLHttpRequestFetchAxios
语法回调式PromisePromise
错误处理通过状态码判断只有网络错误才 reject自动处理 HTTP 错误
请求取消xhr.abort()AbortControllerCancelToken
拦截器✅ 有
默认 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);

JSONP示意

2. CORS(服务器端配置)

服务器通过 HTTP 响应头告知浏览器是否允许跨域:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

CORS配置示意

所有跨域,都需要经过服务端的允许与配合。


六、浏览器存储

三种存储方式对比

特性CookielocalStoragesessionStorage
存储容量4KB5~10MB5~10MB
生命周期可设置过期时间永久(需手动清除)会话级(标签页关闭即清除)
数据作用域同域名下所有页面同域名下所有页面同域名且同标签页
HTTP 请求自动携带✅ 是❌ 否❌ 否
访问权限前端 + 后端仅前端仅前端
存储格式字符串键值对字符串键值对(需 JSON)字符串键值对(需 JSON)
安全性可设置 HttpOnlySecureSameSite明文,需防 XSS明文,需防 XSS
  • 大小限制 4KB
  • 每次 HTTP 请求都会携带到服务端(增加请求数据量)
  • 重要安全属性:
    • HttpOnly:禁止 JS 访问,防止 XSS
    • Secure:只在 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');

<< 返回首页