浏览器面试题及详细答案 88道(34-44)
《前后端面试题
》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。
文章目录
- 一、本文面试题目录
- 34. HTTP 的缓存机制是怎样的?
- 35. 浏览器资源缓存的位置有哪些?协商缓存和强缓存的区别是什么?
- 浏览器资源缓存的位置(按优先级从高到低):
- 协商缓存和强缓存的区别:
- 36. 为什么需要浏览器缓存?
- 37. POST 和 GET 的区别是什么?
- 38. 输入 URL 之后,页面会发生什么?
- 39. 什么是浏览器的同源策略?哪些操作会受其限制?如何解决跨域问题?
- 同源策略(Same-Origin Policy):
- 受同源策略限制的操作:
- 解决跨域问题的合法方式:
- 40. 什么是 CORS?如何配置 CORS?
- CORS(Cross-Origin Resource Sharing,跨域资源共享):
- CORS 配置(服务器端):
- 41. 什么是 JSONP?它的原理是什么?
- JSONP(JSON with Padding):
- 原理:
- 42. 浏览器本地存储方式及使用场景有哪些?(包含 cookie、localStorage、sessionStorage 及其他方式)
- 43. IndexedDB 的特点和使用场景是什么?
- IndexedDB 的特点:
- 使用场景:
- 44. Cookie 有哪些字段?作用分别是什么?浏览器如何管理和存储 cookie?
- Cookie 的核心字段及作用:
- 浏览器对 Cookie 的管理和存储:
一、本文面试题目录
34. HTTP 的缓存机制是怎样的?
HTTP 缓存机制是浏览器为了减少网络请求、提升页面加载速度而采用的资源存储与复用策略,主要分为强缓存和协商缓存两类,工作流程如下:
- 强缓存:浏览器直接从本地缓存读取资源,不发送请求到服务器。
- 依赖响应头字段
Expires
(HTTP/1.0,基于绝对时间,如Expires: Wed, 23 Aug 2025 12:00:00 GMT
)或Cache-Control
(HTTP/1.1,基于相对时间,优先级更高,如Cache-Control: max-age=3600
表示缓存1小时)。 - 若资源未过期,直接使用本地缓存(状态码
200 OK (from cache)
)。
- 依赖响应头字段
- 协商缓存:强缓存失效后,浏览器发送请求到服务器,由服务器判断资源是否更新。
- 依赖请求头
If-Modified-Since
与响应头Last-Modified
(基于资源修改时间),或请求头If-None-Match
与响应头ETag
(基于资源内容哈希)。 - 若资源未更新,服务器返回
304 Not Modified
,浏览器使用本地缓存;若更新,返回200 OK
并携带新资源。
- 依赖请求头
示例:
服务器响应头配置强缓存+协商缓存:
HTTP/1.1 200 OK
Cache-Control: max-age=3600 // 强缓存1小时
Last-Modified: Tue, 01 Aug 2025 10:00:00 GMT // 协商缓存(修改时间)
ETag: "abc123" // 协商缓存(内容哈希)
35. 浏览器资源缓存的位置有哪些?协商缓存和强缓存的区别是什么?
浏览器资源缓存的位置(按优先级从高到低):
- Memory Cache(内存缓存):存储临时资源(如脚本、样式),关闭标签页后释放,读取速度最快。
- Disk Cache(磁盘缓存):存储长期资源(如图片、大型文件),关闭浏览器后仍保留,读取速度次之。
- Service Worker Cache:由开发者通过 Service Worker 手动管理的缓存,可离线访问,需代码配置。
- Push Cache(推送缓存):HTTP/2 特有的临时缓存,仅在会话中有效,优先级最低。
协商缓存和强缓存的区别:
维度 | 强缓存 | 协商缓存 |
---|---|---|
是否发请求 | 不发送请求,直接用本地缓存 | 发送请求,由服务器判断是否可用 |
控制字段 | Expires 、Cache-Control | Last-Modified/If-Modified-Since 、ETag/If-None-Match |
状态码 | 200 OK (from cache) | 304 Not Modified |
资源更新判断 | 浏览器本地判断(过期时间) | 服务器判断(内容是否变化) |
适用场景 | 静态不变资源(如图标) | 频繁更新但非实时的资源(如新闻) |
36. 为什么需要浏览器缓存?
浏览器缓存的核心价值在于优化性能与用户体验,具体原因如下:
- 减少网络请求:复用本地缓存资源,降低服务器压力和带宽消耗。
- 提升加载速度:从本地读取资源(毫秒级)比网络请求(秒级)快得多,尤其对弱网环境友好。
- 支持离线访问:通过 Service Worker 缓存可实现离线打开页面(如 PWA 应用)。
- 降低成本:减少重复资源传输,节省服务器和 CDN 的运营成本。
- 优化用户体验:页面加载更快,减少等待时间,降低用户流失率。
37. POST 和 GET 的区别是什么?
GET 和 POST 是 HTTP 中最常用的两种请求方法,核心区别如下:
维度 | GET | POST |
---|---|---|
用途 | 获取资源(无副作用,幂等) | 提交资源(可能有副作用,非幂等) |
参数位置 | URL query 字符串(可见) | 请求体(不可见,更安全) |
参数长度 | 受 URL 长度限制(约 2KB) | 无限制(由服务器配置决定) |
缓存 | 可被缓存(如浏览器历史记录) | 默认不缓存 |
后退/刷新 | 无影响(幂等) | 可能重复提交(需防重放) |
编码类型 | 仅支持 ASCII 字符 | 支持多种编码(如 multipart/form-data 上传文件) |
示例:
- GET 请求(获取用户信息):
GET /api/user?id=123 HTTP/1.1
- POST 请求(提交表单):
POST /api/login HTTP/1.1 Content-Type: application/x-www-form-urlencodedusername=test&password=123
38. 输入 URL 之后,页面会发生什么?
从输入 URL 到页面渲染完成,经历以下核心步骤:
- URL 解析:浏览器解析 URL(协议、域名、路径等),若为非标准协议(如
mailto:
),调用对应程序。 - DNS 解析:将域名(如
www.example.com
)转换为 IP 地址(如192.168.1.1
),优先查本地 DNS 缓存,再查 DNS 服务器。 - TCP 三次握手:建立与服务器的 TCP 连接(客户端→服务器:SYN;服务器→客户端:SYN+ACK;客户端→服务器:ACK)。
- 发送 HTTP 请求:通过 TCP 连接发送请求(如
GET /index.html
),包含请求头(如Host
、User-Agent
)。 - 服务器处理请求:服务器接收请求,处理后返回 HTTP 响应(状态码、响应头、响应体)。
- TCP 四次挥手:若为短连接,请求完成后断开 TCP 连接(客户端→服务器:FIN;服务器→客户端:ACK;服务器→客户端:FIN;客户端→服务器:ACK)。
- 浏览器解析与渲染:
- 解析 HTML 生成 DOM 树,解析 CSS 生成 CSSOM 树,合并为渲染树(Render Tree)。
- 布局(Layout):计算元素位置和大小;绘制(Paint):将元素绘制到屏幕;合成(Composite):分层显示提升性能。
- 执行 JavaScript:若有脚本,通过 JS 引擎执行,可能修改 DOM/CSSOM,触发重绘/回流。
39. 什么是浏览器的同源策略?哪些操作会受其限制?如何解决跨域问题?
同源策略(Same-Origin Policy):
浏览器的安全机制,规定协议、域名、端口三者均相同的 URL 为“同源”,不同源的页面间默认禁止相互访问资源。
受同源策略限制的操作:
- DOM 访问:无法通过
iframe
或window.open
获取不同源页面的 DOM。 - AJAX/fetch 请求:禁止向不同源服务器发送 HTTP 请求。
- Cookie/LocalStorage 访问:不同源页面无法读取彼此的存储数据。
- Canvas 图像操作:若图像来自不同源,
toDataURL()
等方法会被阻塞。
解决跨域问题的合法方式:
- CORS(跨域资源共享):服务器在响应头中配置
Access-Control-Allow-Origin
允许指定域名访问。
示例(服务器响应头):Access-Control-Allow-Origin: https://example.com
- JSONP:利用
<script>
标签不受同源限制的特性,通过回调函数获取数据。
示例:<script src="https://api.example.com/data?callback=handleData"></script> <script>function handleData(data) { console.log(data); } // 接收跨域数据 </script>
- 代理服务器:通过同源服务器转发请求(如 Nginx 反向代理)。
Nginx 配置示例:location /api {proxy_pass https://api.example.com; # 转发跨域请求 }
- WebSocket:全双工通信协议,握手阶段允许跨域,适用于实时通信。
40. 什么是 CORS?如何配置 CORS?
CORS(Cross-Origin Resource Sharing,跨域资源共享):
一种基于 HTTP 头的机制,允许服务器指定哪些跨域源可以访问其资源,是解决跨域 AJAX 请求的标准方案。
CORS 配置(服务器端):
核心通过响应头控制跨域权限,常用字段:
Access-Control-Allow-Origin
:允许访问的源(如*
表示所有源,https://example.com
表示指定源)。Access-Control-Allow-Methods
:允许的请求方法(如GET, POST, PUT
)。Access-Control-Allow-Headers
:允许的请求头(如Content-Type, Token
)。Access-Control-Allow-Credentials
:是否允许携带 Cookie(设为true
时,Access-Control-Allow-Origin
不能为*
)。Access-Control-Max-Age
:预检请求(OPTIONS)的缓存时间(如86400
秒)。
示例(Node.js Express 配置):
const express = require('express');
const app = express();app.use((req, res, next) => {res.setHeader('Access-Control-Allow-Origin', 'https://example.com'); // 允许指定源res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT'); // 允许的方法res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Token'); // 允许的头res.setHeader('Access-Control-Allow-Credentials', 'true'); // 允许携带Cookienext();
});app.get('/data', (req, res) => {res.json({ message: '跨域数据' });
});
app.listen(3000);
41. 什么是 JSONP?它的原理是什么?
JSONP(JSON with Padding):
一种非标准的跨域数据获取方式,利用 <script>
标签不受同源策略限制的特性实现。
原理:
- 客户端定义一个回调函数(如
handleData
),用于接收跨域数据。 - 动态创建
<script>
标签,src
指向跨域服务器的接口,并在 URL 中携带回调函数名(如https://api.example.com/data?callback=handleData
)。 - 服务器接收请求后,将数据包裹在回调函数中返回(如
handleData({ "name": "test" })
)。 <script>
标签加载并执行返回的 JS 代码,触发回调函数,客户端获取数据。
示例:
<!-- 客户端 -->
<script>// 定义回调函数function handleData(data) {console.log('跨域数据:', data); // 输出 { "name": "test" }}
</script>
<!-- 动态创建script标签发起JSONP请求 -->
<script src="https://api.example.com/data?callback=handleData"></script>
服务器返回内容(Node.js 示例):
// 服务器端(Node.js)
const http = require('http');
http.createServer((req, res) => {const url = new URL(req.url, 'http://localhost');const callback = url.searchParams.get('callback'); // 获取回调函数名const data = { name: 'test' };res.end(`${callback}(${JSON.stringify(data)})`); // 返回包裹数据的回调
}).listen(8080);
局限性:仅支持 GET 请求,存在 XSS 风险(需服务器过滤回调函数名)。
42. 浏览器本地存储方式及使用场景有哪些?(包含 cookie、localStorage、sessionStorage 及其他方式)
浏览器本地存储是在客户端保存数据的机制,常见方式及场景如下:
-
Cookie:
- 特点:容量小(约 4KB),随 HTTP 请求自动发送,可设置过期时间,受同源策略限制。
- 场景:身份认证(如 Session ID)、记住登录状态、跟踪用户行为。
- 示例:
document.cookie = "username=test; expires=Wed, 23 Aug 2025 12:00:00 GMT; path=/";
-
localStorage:
- 特点:容量较大(约 5-10MB),永久存储(除非手动删除),仅客户端访问,同源共享。
- 场景:存储用户偏好设置(如主题、语言)、离线数据缓存。
- 示例:
localStorage.setItem('theme', 'dark'); const theme = localStorage.getItem('theme');
-
sessionStorage:
- 特点:容量同 localStorage,仅在当前会话(标签页)有效,关闭标签页后删除。
- 场景:临时表单数据、单页应用的状态管理。
- 示例:
sessionStorage.setItem('tempData', 'hello');
-
IndexedDB:
- 特点:大型 NoSQL 数据库(容量无明确限制),支持事务、索引,异步操作。
- 场景:存储大量结构化数据(如离线应用的本地数据库)。
-
Web SQL:
- 特点:关系型数据库(基于 SQLite),已被 W3C 废弃,仅部分浏览器支持。
- 场景:兼容性要求低的旧项目(不推荐新应用使用)。
-
Service Worker Cache:
- 特点:由 Service Worker 管理的缓存,可拦截请求,支持离线访问。
- 场景:PWA 应用的离线资源缓存(如页面、图片)。
43. IndexedDB 的特点和使用场景是什么?
IndexedDB 的特点:
- 大容量存储:无明确容量限制(远大于 localStorage 的 5-10MB),适合存储大量数据。
- NoSQL 数据库:以键值对存储,支持复杂数据结构(对象、数组等)。
- 异步操作:所有操作(增删改查)均为异步,不阻塞主线程。
- 事务支持:操作在事务中执行,确保数据一致性(要么全部成功,要么全部失败)。
- 索引功能:可对字段创建索引,提升查询效率。
- 同源限制:仅允许访问同源下的数据库。
- 持久化存储:数据永久保存,除非手动删除。
使用场景:
- 离线应用数据存储:如 PWA 应用在离线时保存用户操作数据,联网后同步。
- 大型数据缓存:存储用户历史记录(如聊天记录、浏览记录)、离线地图数据。
- 高性能查询:需频繁查询的结构化数据(如商品列表、联系人信息)。
示例(基本操作):
// 打开或创建数据库(版本1)
const request = indexedDB.open('myDB', 1);// 数据库创建/升级时触发
request.onupgradeneeded = (event) => {const db = event.target.result;// 创建存储对象(类似表),主键为idif (!db.objectStoreNames.contains('users')) {const store = db.createObjectStore('users', { keyPath: 'id' });// 创建索引(按name查询)store.createIndex('nameIndex', 'name', { unique: false });}
};// 打开成功后操作数据
request.onsuccess = (event) => {const db = event.target.result;// 开启事务(读写模式)const transaction = db.transaction('users', 'readwrite');const store = transaction.objectStore('users');// 添加数据store.add({ id: 1, name: 'Alice', age: 20 });// 查询数据(通过主键)store.get(1).onsuccess = (e) => {console.log('查询结果:', e.target.result); // { id:1, name: 'Alice', ... }};// 事务完成transaction.oncomplete = () => db.close();
};
44. Cookie 有哪些字段?作用分别是什么?浏览器如何管理和存储 cookie?
Cookie 的核心字段及作用:
字段 | 作用 |
---|---|
name=value | 键值对,存储具体数据(如 username=test )。 |
expires | 过期时间(绝对时间,如 Wed, 23 Aug 2025 12:00:00 GMT ),默认会话结束后失效。 |
max-age | 过期秒数(相对时间,如 3600 表示1小时后失效),优先级高于 expires 。 |
domain | 允许访问 Cookie 的域名(如 example.com 表示子域名 a.example.com 也可访问)。 |
path | 允许访问 Cookie 的路径(如 /admin 表示仅 /admin 路径下的页面可访问)。 |
secure | 仅在 HTTPS 协议下传输 Cookie(HTTP 环境下不发送)。 |
HttpOnly | 禁止 JS 通过 document.cookie 访问 Cookie,防止 XSS 攻击。 |
SameSite | 限制跨站请求时 Cookie 的发送(Strict /Lax /None ),防止 CSRF 攻击。 |
浏览器对 Cookie 的管理和存储:
- 存储位置:以文件形式存储在本地(不同浏览器路径不同,如 Chrome 存储在 SQLite 数据库中)。
- 发送规则:
- 仅向
domain
和path
匹配的 URL 发送 Cookie。 - 若设置
secure
,仅在 HTTPS 连接中发送。 - 遵循同源策略,不同源页面无法读取彼此的 Cookie。
- 仅向
- 过期处理:
- 未设置
expires
或max-age
:会话 Cookie,关闭浏览器后删除。 - 设置过期时间:到达时间后自动删除。
- 未设置
- 数量与大小限制:每个域名下 Cookie 数量约 50 个,单个 Cookie 大小约 4KB。
示例(设置带字段的 Cookie):
// 设置一个24小时后过期、仅HTTPS发送、禁止JS访问的Cookie
document.cookie = "sessionId=abc123; max-age=86400; secure; HttpOnly; SameSite=Lax";