0%

前端面试官题库——全面的前端技术面试题集合

这是一份全面的前端技术面试题库,涵盖从基础到高级的前端技术知识点,帮助面试官全面考察候选人的技术能力。

HTML5专题

1. 语义化HTML

问题1:HTML语义化的作用是什么?请举例说明常用语义化标签。

点击查看答案

答案:

  • 作用:

    • 提高代码可读性和可维护性
    • 有利于搜索引擎优化(SEO)
    • 便于无障碍访问(Accessibility)
    • 明确内容结构,提升用户体验
  • 常用语义化标签:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <header> <!-- 页面或章节的头部 -->
    <nav> <!-- 导航链接 -->
    <main> <!-- 主要内容 -->
    <article> <!-- 独立的文章内容 -->
    <section> <!-- 内容区块 -->
    <aside> <!-- 侧边栏内容 -->
    <footer> <!-- 页面或章节的底部 -->
    <figure> <!-- 媒体内容(图片、图表等) -->
    <figcaption> <!-- 媒体内容的说明 -->
    <time> <!-- 时间 -->
    <address> <!-- 联系信息 -->

问题2:HTML5新增了哪些重要特性?

点击查看答案

答案:

  • 语义化标签: header, nav, main, article, section, aside, footer, figure, figcaption
  • 表单增强: 新的输入类型(email, url, date, time等)和验证属性
  • 多媒体支持: <audio><video> 标签
  • Canvas和SVG: 图形绘制能力
  • 本地存储: localStorage, sessionStorage, IndexedDB
  • 地理定位: Geolocation API
  • Web Workers: 后台线程处理
  • WebSocket: 全双工通信
  • 拖拽API: Drag and Drop

问题3:HTML5离线存储与浏览器缓存的区别是什么?

点击查看答案

答案:

  • HTML5离线存储:

    • Manifest文件方式,应用缓存(Application Cache)
    • 现在推荐使用Service Worker + Cache API
    • 可以在无网络情况下使用应用
    • 需要主动更新manifest或sw文件
  • 浏览器缓存:

    • 基于HTTP头的缓存机制
    • 强缓存(Expires, Cache-Control)和协商缓存(Last-Modified, ETag)
    • 缓存策略更灵活,由服务器控制
    • 需要网络连接才能获取新资源

2. 浏览器存储

问题4:浏览器存储方式有哪些?各有什么特点和限制?

点击查看答案

答案:

  • cookie(4KB左右):

    1
    2
    // 设置cookie
    document.cookie = "name=value; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/";
    • 容量限制:约4KB
    • 特点:每次HTTP请求都会携带,可设置过期时间
    • 用途:用户会话、登录状态
  • localStorage(5-10MB):

    1
    2
    localStorage.setItem('key', 'value');
    localStorage.getItem('key');
    • 容量限制:约5-10MB(不同浏览器不同)
    • 特点:持久存储,关闭浏览器不丢失
    • 用途:用户偏好设置、应用状态
  • sessionStorage(5-10MB):

    1
    2
    sessionStorage.setItem('key', 'value');
    sessionStorage.getItem('key');
    • 容量限制:约5-10MB
    • 特点:仅在当前会话期间有效,关闭标签页即丢失
    • 用途:临时数据、表单数据
  • IndexedDB(存储限制很大):

    1
    2
    3
    4
    const request = indexedDB.open('MyDB', 1);
    request.onsuccess = function(event) {
    const db = event.target.result;
    };
    • 容量限制:很大(通常限制为磁盘空间的某个百分比)
    • 特点:事务性、异步、支持索引
    • 用途:复杂数据存储、离线应用
  • Web Storage的共同特点:

    • 只能在同源下使用
    • 存储的数据类型仅限字符串
    • 不参与HTTP请求

问题5:如何在多个浏览器标签页间共享数据?

点击查看答案

答案:

  • Broadcast Channel API:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 创建广播频道
    const bc = new BroadcastChannel('test_channel');

    // 发送消息
    bc.postMessage('Hello other tabs!');

    // 接收消息
    bc.onmessage = function (ev) {
    console.log(ev.data);
    };
  • localStorage事件:

    1
    2
    3
    4
    5
    6
    7
    // 监听storage事件
    window.addEventListener('storage', function(e) {
    console.log('Storage changed:', e.key, e.newValue);
    });

    // 其他标签页修改localStorage会触发事件
    localStorage.setItem('key', 'value');
  • SharedWorker:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // main.js
    const worker = new SharedWorker('worker.js');
    worker.port.start();
    worker.port.postMessage('Hello from main thread');

    // worker.js
    const connections = [];

    self.onconnect = function(e) {
    const port = e.ports[0];
    connections.push(port);

    port.onmessage = function(e) {
    // 向所有连接的端口广播消息
    connections.forEach(conn => conn.postMessage(e.data));
    };
    };

HTTP协议专题

3. HTTP方法

问题6:GET和POST方法的区别是什么?

点击查看答案

答案:

  • 数据传输位置:

    • GET:数据放在URL中,通过查询字符串传递
    • POST:数据放在请求体中传输
  • 数据大小限制:

    • GET:受URL长度限制(通常2-8KB)
    • POST:理论上无限制,但服务器和浏览器会有实际限制
  • 安全性:

    • GET:数据暴露在URL中,不安全,不应传输敏感信息
    • POST:数据在请求体中,相对安全
  • 幂等性:

    • GET:幂等操作,多次请求结果相同
    • POST:非幂等操作,多次请求可能产生不同结果
  • 缓存:

    • GET:可以被浏览器缓存
    • POST:通常不会被缓存
  • 书签:

    • GET:可以被收藏为书签
    • POST:不能被收藏为书签
  • 历史记录:

    • GET:参数会保存在浏览器历史记录中
    • POST:参数不会保存在历史记录中

问题7:HTTP状态码有哪些分类?请列举常用状态码。

点击查看答案

答案:

  • 1xx:信息性状态码

    • 100 Continue:继续
    • 101 Switching Protocols:切换协议
  • 2xx:成功状态码

    • 200 OK:请求成功
    • 201 Created:资源创建成功
    • 204 No Content:请求成功但无返回内容
  • 3xx:重定向状态码

    • 301 Moved Permanently:永久重定向
    • 302 Found:临时重定向
    • 304 Not Modified:资源未修改(缓存有效)
  • 4xx:客户端错误状态码

    • 400 Bad Request:请求语法错误
    • 401 Unauthorized:未授权
    • 403 Forbidden:禁止访问
    • 404 Not Found:资源未找到
    • 405 Method Not Allowed:方法不允许
    • 429 Too Many Requests:请求过多
  • 5xx:服务器错误状态码

    • 500 Internal Server Error:服务器内部错误
    • 502 Bad Gateway:网关错误
    • 503 Service Unavailable:服务不可用
    • 504 Gateway Timeout:网关超时

4. 跨域问题

问题8:什么是跨域?有哪些解决跨域的方法?

点击查看答案

答案:

  • 跨域定义: 当协议、域名、端口号任一不同时,即构成跨域

  • 跨域解决方法:

    1. CORS(跨域资源共享):

      1
      2
      3
      4
      5
      6
      7
      // 服务端设置响应头
      app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
      res.header('Access-Control-Allow-Headers', 'Content-Type');
      next();
      });
    2. JSONP:

      1
      2
      3
      4
      5
      6
      7
      8
      // 动态创建script标签
      function jsonp(url, callback) {
      const script = document.createElement('script');
      script.src = `${url}?callback=${callback}`;
      document.head.appendChild(script);
      }

      // 后端返回:callback(data)
    3. 代理:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // Webpack Dev Server代理
      module.exports = {
      devServer: {
      proxy: {
      '/api': {
      target: 'http://localhost:3000',
      changeOrigin: true
      }
      }
      }
      };
    4. Nginx反向代理:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      server {
      listen 80;
      server_name localhost;

      location /api/ {
      proxy_pass http://backend-server/;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      }
      }
    5. PostMessage:

      1
      2
      3
      4
      5
      6
      7
      8
      // 发送消息
      otherWindow.postMessage(message, targetOrigin);

      // 接收消息
      window.addEventListener('message', function(event) {
      if (event.origin !== 'http://example.com') return;
      console.log(event.data);
      });

浏览器专题

5. 浏览器渲染

问题9:浏览器的渲染过程是怎样的?

点击查看答案

答案:
浏览器渲染过程主要包括以下几个步骤:

  1. 构建DOM树:

    • 解析HTML文档,将标签转换为DOM节点
    • 形成DOM树结构
  2. 构建CSSOM树:

    • 解析CSS样式规则
    • 形成CSS对象模型树
  3. 构建渲染树:

    • 合并DOM树和CSSOM树
    • 包含可见节点及其样式信息
    • 隐藏元素(display:none)不会出现在渲染树中
  4. 布局(Layout/Reflow):

    • 计算每个节点在页面中的确切位置和大小
    • 确定各个元素的位置和几何信息
  5. 绘制(Paint):

    • 将渲染树的每个节点转换为屏幕上的实际像素
    • 将视觉信息填充到图层中
  6. 合成(Composite):

    • 将多个图层按照正确的层级关系组合
    • 显示到屏幕上

性能优化建议:

  • 减少DOM操作次数
  • 避免频繁的样式计算
  • 使用transform和opacity来触发合成层
  • 批量修改样式

问题10:重排(Reflow)和重绘(Repaint)的区别是什么?

点击查看答案

答案:

重排(Reflow):

  • 概念:计算元素几何信息(位置、尺寸)的过程
  • 触发条件:
    • 页面初始化
    • 添加/删除可见DOM元素
    • 元素位置改变
    • 元素尺寸改变(边距、填充、边框、宽高)
    • 内容改变(文本改变或图片被替换)
    • 页面渲染初始化
    • 浏览器窗口尺寸改变

重绘(Repaint):

  • 概念:更新元素外观的过程,不改变几何信息
  • 触发条件:
    • 颜色改变
    • 背景改变
    • 可见性改变(visibility)

区别:

  • 重排一定会导致重绘,重绘不一定需要重排
  • 重排消耗更大,因为它需要重新计算几何信息
  • 重绘相对轻量,只需要更新外观

优化策略:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 避免频繁的DOM操作
// 错误示例:
for(let i = 0; i < 1000; i++) {
div.style.left = i + 'px'; // 每次都触发重排
div.style.top = i + 'px';
}

// 正确示例:
div.style.cssText = 'left: 100px; top: 100px;'; // 一次性应用
// 或者
const newLeft = 100;
const newTop = 100;
Object.assign(div.style, { left: newLeft + 'px', top: newTop + 'px' });

6. 缓存机制

问题11:浏览器缓存机制是怎样的?有哪些缓存策略?

点击查看答案

答案:
浏览器缓存主要分为两大类:

1. 强缓存:

  • Expires: HTTP/1.0时代的头部,指定过期时间(绝对时间)
    1
    Expires: Wed, 21 Oct 2025 07:28:00 GMT
  • Cache-Control: HTTP/1.1引入,优先级高于Expires
    1
    2
    3
    4
    5
    Cache-Control: max-age=3600 // 缓存1小时
    Cache-Control: no-cache // 不使用强缓存,但可使用协商缓存
    Cache-Control: no-store // 不缓存
    Cache-Control: public // 可被任何缓存
    Cache-Control: private // 仅用户浏览器可缓存

2. 协商缓存:

  • Last-Modified / If-Modified-Since:
    1
    2
    3
    4
    // 响应头
    Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
    // 请求头
    If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
  • ETag / If-None-Match:
    1
    2
    3
    4
    // 响应头
    ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
    // 请求头
    If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

缓存策略:

  1. 优先级: Cache-Control > Expires
  2. 缓存过程: 强缓存 -> 协商缓存 -> 重新请求
  3. 最佳实践:
    • 静态资源使用强缓存(长期有效)
    • 动态资源使用协商缓存
    • 合理设置缓存时间

7. WebSocket

问题12:WebSocket与HTTP的区别是什么?适用于什么场景?

点击查看答案

答案:

WebSocket与HTTP的区别:

特性HTTPWebSocket
连接方式请求-响应模式全双工通信
连接持久性短连接,请求后关闭长连接,持续通信
通信方式客户端发起,服务器响应双方可随时发送数据
开销每次请求都包含头部信息首次握手后数据帧较小
实时性需要轮询或长轮询真正实时通信

WebSocket实现示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 客户端
const socket = new WebSocket('ws://localhost:8080');

socket.onopen = function(event) {
console.log('连接已建立');
socket.send('Hello Server!');
};

socket.onmessage = function(event) {
console.log('收到消息:', event.data);
};

socket.onclose = function(event) {
console.log('连接已关闭');
};

// 服务端(Node.js示例)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('收到:', message);
ws.send('Echo: ' + message);
});
});

适用场景:

  • 聊天应用
  • 在线游戏
  • 实时协作工具
  • 股票行情
  • 在线教育
  • 直播弹幕

8. Content-Type

问题13:常见的Content-Type有哪些?如何正确设置?

点击查看答案

答案:

常见Content-Type:

文本类型:

  • text/plain - 纯文本
  • text/html - HTML文档
  • text/css - CSS样式表
  • application/json - JSON数据
  • application/xml - XML数据
  • text/javascript - JavaScript代码

图片类型:

  • image/jpeg - JPEG图片
  • image/png - PNG图片
  • image/gif - GIF图片
  • image/svg+xml - SVG矢量图

文件类型:

  • application/pdf - PDF文档
  • application/zip - ZIP压缩文件
  • application/msword - Word文档
  • application/vnd.ms-excel - Excel文档

表单数据:

  • application/x-www-form-urlencoded - 传统表单数据
  • multipart/form-data - 文件上传表单
  • application/json - JSON数据

正确设置方法:

前端设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Ajax请求
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});

// Axios设置
axios.post('/api/data', data, {
headers: {
'Content-Type': 'application/json'
}
});

后端设置(Express示例):

1
2
3
4
5
6
7
8
9
app.get('/api/data', (req, res) => {
res.setHeader('Content-Type', 'application/json');
res.json({ message: 'Success' });
});

app.get('/api/file', (req, res) => {
res.setHeader('Content-Type', 'application/octet-stream');
res.download('./file.pdf');
});

CSS专题

9. 引入方式

问题14:CSS的引入方式有哪些?有什么区别?

点击查看答案

答案:

1. 内联样式(Inline Styles):

1
<div style="color: red; font-size: 14px;">内联样式</div>
  • 优先级最高
  • 维护性差,不利于复用

2. 内部样式(Internal Stylesheet):

1
2
3
4
5
<head>
<style>
.my-class { color: red; }
</style>
</head>
  • 仅在当前页面有效
  • 不利于多页面复用

3. 外部样式(External Stylesheet):

1
<link rel="stylesheet" href="style.css">
  • 可以在多个页面中复用
  • 有利于浏览器缓存
  • 推荐使用

4. 导入样式(@import):

1
@import url('style.css');
  • 优先级较低
  • 会阻塞CSS加载,不推荐使用

优先级(从高到低):

  1. !important
  2. 内联样式
  3. ID选择器
  4. 类选择器、属性选择器、伪类选择器
  5. 元素选择器、伪元素选择器
  6. 继承的样式
  7. 浏览器默认样式

10. 伪类和伪元素

问题15:CSS伪类和伪元素的区别是什么?常用有哪些?

点击查看答案

答案:

伪类(Pseudo-classes):

  • 用于选择元素的特定状态
  • 语法::pseudo-class
  • 表示元素的某种状态

常用伪类:

1
2
3
4
5
6
7
8
9
10
11
12
a:link { color: blue; }          /* 未访问的链接 */
a:visited { color: purple; } /* 已访问的链接 */
a:hover { color: red; } /* 鼠标悬停 */
a:active { color: orange; } /* 激活状态 */
a:focus { outline: 2px solid blue; } /* 获得焦点 */

input:disabled { background: #eee; } /* 禁用状态 */
input:checked + label { color: green; } /* 选中状态 */

li:first-child { font-weight: bold; } /* 第一个子元素 */
li:last-child { border-bottom: none; } /* 最后一个子元素 */
tr:nth-child(odd) { background: #f0f0f0; } /* 奇数行 */

伪元素(Pseudo-elements):

  • 用于选择元素的特定部分
  • 语法:::pseudo-element
  • 创建虚拟的DOM元素

常用伪元素:

1
2
3
4
5
6
7
8
9
10
11
p::first-letter { font-size: 2em; }    /* 首字母 */
p::first-line { font-weight: bold; } /* 首行 */

div::before { content: "★ "; } /* 前置内容 */
div::after { content: " ★"; } /* 后置内容 */

.quote::before { /* 引用装饰 */
content: """;
font-size: 2em;
color: #ccc;
}

区别总结:

  • 伪类选择已有元素的不同状态
  • 伪元素创建虚拟的DOM元素
  • 伪类用单冒号,伪元素用双冒号
  • 伪类不创建新元素,伪元素创建新内容

11. Flex布局

问题16:Flex布局的原理是什么?如何使用?

点击查看答案

答案:

Flex布局原理:
Flex布局由弹性容器(flex container)和弹性项目(flex items)组成,通过在一维空间内调整项目的大小来填充可用空间。

容器属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.flex-container {
display: flex; /* 开启flex布局 */

/* 主轴方向 */
flex-direction: row | row-reverse | column | column-reverse;

/* 换行 */
flex-wrap: nowrap | wrap | wrap-reverse;

/* 主轴对齐 */
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;

/* 交叉轴对齐 */
align-items: stretch | flex-start | flex-end | center | baseline;

/* 多轴对齐 */
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

项目属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.flex-item {
/* 放大比例 */
flex-grow: 1;

/* 缩小比例 */
flex-shrink: 1;

/* 基础大小 */
flex-basis: auto | 100px;

/* 简写 */
flex: 1; /* 相当于 flex: 1 1 0% */

/* 单个项目对齐 */
align-self: auto | flex-start | flex-end | center | baseline | stretch;

/* 排序 */
order: 0; /* 数值越小越靠前 */
}

经典布局示例:

1
2
3
4
5
6
<div class="container">
<div class="header">头部</div>
<div class="main">主要内容</div>
<div class="sidebar">侧边栏</div>
<div class="footer">底部</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.container {
display: flex;
flex-direction: column;
height: 100vh;
}

.header, .footer {
flex: 0 0 auto; /* 不放大,不缩小,根据内容确定大小 */
background: #ccc;
}

.main {
flex: 1; /* 占据剩余空间 */
display: flex;
}

.sidebar {
flex: 0 0 200px; /* 固定宽度200px */
background: #eee;
}

12. 盒模型

问题17:CSS盒模型有哪几种?如何理解?

bulb