标签

Browser

网络浏览器或互联网浏览器是一种软件应用,用于检索、展示和浏览世界广域网上的信息资源。

Browser
前端2026年5月27日 01:13
浏览器渲染页面的详细过程是怎样的?从收到 HTML 到显示画面,浏览器做了这五步: 1. **解析 HTML → DOM 树**:字节 → 字符 → Token → 节点 → DOM 树。遇到 `<script>` 暂停解析,先下载执行 JS(因为 JS 可能修改 DOM)。遇到 CSS/图片等资源不阻塞解析,并行下载。 2. **解析 CSS → CSSOM 树**:类似 HTML 解析过程。CSS 解析不阻塞 DOM 构建,但阻塞渲染(没 CSSOM 不能渲染)。 3. **DOM + CSSOM → Render 树**:合并两棵树,可见元素进树,`display: none` 的元素排除。 4. **Layout(重排)**:计算每个可见元素的精确位置和大小。 5. **Paint(绘制)**:将 Layout 结果转成屏幕像素。 之后还有 Composite(合成)——把页面分层,GPU 做变换和合成,这就是为什么 `transform` 和 `opacity` 动画不触发重排。 ## 追问 ### 为什么 CSS 要放在 head 中,JS 要放在 body 底部? CSS 放 head:浏览器尽早下载 CSSOM,避免渲染出无样式的白屏(FOUC)。JS 放底部:`<script>` 会阻塞 DOM 解析,放在底部能先渲染出页面内容再加载 JS,用户感知更快。`<script defer>` 下载不阻塞解析,DOM 构建完后执行,也是好选择。 ### 重排和重绘哪个更贵? 重排贵得多。重排要重新计算布局,可能触发整个子树的级联重排。重绘只重新画像素。`transform` 和 `opacity` 不触发重排重绘(在合成线程处理),性能最好。能动画就用 transform。 ### 为什么 transform 动画不卡? 因为它发生在合成器线程(Compositor Thread),而不是主线程。主线程被 JS 阻塞时,合成器线程照常工作。`top`/`left` 动画会触发 Layout → Paint → Composite 全流程,走主线程,会卡。
前端2026年5月27日 01:10
Chrome 打开一个页面需要启动多少进程?分别有哪些进程?Chrome 是多进程架构,主要进程: - **Browser 进程(1 个)**:主进程,管 UI(地址栏、书签)、网络请求、文件访问。协调其他进程。 - **Renderer 进程(每个标签页一个)**:渲染页面内容(HTML、CSS、JS)。沙箱隔离,一个页面崩不影响其他页面。 - **GPU 进程(1 个)**:处理 GPU 任务(CSS 3D 变换、WebGL、视频解码)。 - **Plugin 进程(按需)**:隔离运行的插件(Flash 等,现已很少)。 - **Network 进程(1 个,较新版本)**:独立的网络进程。 - **Utility 进程(按需)**:音频、扩展等。 同一站点(same-site)的标签页可能共享 Renderer 进程以节省内存。具体数量取决于你开了多少标签页、多少扩展。 ## 追问 ### 为什么 Chrome 用多进程而不是多线程? 稳定性和安全性。如果一个标签页崩溃或卡死,只影响那个 Renderer 进程,不会拖垮整个浏览器。沙箱机制也只限制单进程的权限。缺点是内存占用高,所以 Chrome 引入了进程共享(同一站点共享 Renderer 进程)。 ### Renderer 进程里是什么? Renderer 进程包含:主线程(JS 执行、样式计算、布局)、合成线程(处理滚动、动画)、Raster 线程(将绘制命令转成位图)、Worker 线程等。主线程阻塞是页面卡顿的主要原因。 ### 内存不够时 Chrome 会怎么做? Chrome 会动态管理:冻结后台标签页的进程(节省内存)、优先杀掉非活动标签页的 Renderer 进程、同一站点合用一个 Renderer 进程。开大量标签页时内存压力还是很大。
前端2026年5月27日 01:09
浏览器为什么要有同源限制?同源策略是浏览器最核心的安全机制——限制一个源(协议+域名+端口都相同)的脚本去访问另一个源的资源。 没有同源限制会怎样?你打开了 `bank.com` 登录了,另一个标签页打开了 `evil.com`。`evil.com` 的 JS 可以直接用 `fetch` 发请求到 `bank.com/api/transfer`——浏览器会自动带上你的登录 cookie,钱就转走了。同源策略阻止了这个。 同源限制主要限制:1) AJAX 跨域请求;2) 跨 iframe/窗口的 DOM 操作;3) localStorage/Cookie 的跨域访问。 跨域解决方案:CORS(服务端设 `Access-Control-Allow-Origin`)、JSONP(老方法,利用 script 标签不受同源限制)、代理(同源服务端转发)。 ## 追问 ### 为什么 script/img 标签不受同源限制? 这是历史原因和功能需求——网页需要加载 CDN 上的脚本和图片。但 `<script>` 加载完会以当前域执行(所以有 XSS 风险),`<img>` 只能渲染不能读取像素数据(防止窃取)。资源加载的宽松和 API 访问的严格是两个层面的事。 ### 同源策略能防止 CSRF 吗? 不完全能。CSRF 的请求能发出去(form 提交、img 加载都可以跨域),同源策略只阻止 JS 读响应。防止 CSRF 得靠 CSRF Token 或 SameSite Cookie。 ### 跨域请求发出去但响应被拦截,服务端收到请求了吗? 收到了。浏览器是收到响应后发现没有 CORS 头才拦截的。所以服务端需要用 CORS 头来控制,不能用"浏览器会拦截"来保护服务端。
前端2024年8月5日 12:50
浏览器有哪些缓存策略?浏览器缓存策略主要是用于提高网页加载速度,减少服务器压力以及节省带宽。以下是几种主要的浏览器缓存策略: 1. **强缓存(Strong Cache)** - `Expires`:这是HTTP/1.0中使用的头信息,用来指定资源到期的时间。如果请求的时间小于Expires的时间,浏览器会直接使用缓存中的资源,而不会向服务器发起请求。 - `Cache-Control`:在HTTP/1.1中引入,比Expires更灵活。常用的指令包括`max-age`(资源最大有效时间)、`no-cache`(每次都要向服务器确认)、`no-store`(完全不缓存),等等。若设置了`max-age`,且缓存时间未过期,则浏览器会直接使用本地缓存。 2. **协商缓存(Negotiation Cache)** - `Last-Modified`和`If-Modified-Since`:服务器在响应中加入`Last-Modified`标头指明资源最后修改时间,浏览器再请求时通过`If-Modified-Since`将这个值发送给服务器,由服务器判断资源是否有更新。 - `ETag`和`If-None-Match`:ETag是资源的唯一标识符,当资源有变动时ETag也会变。浏览器存储资源的ETag,并在下次请求时通过`If-None-Match`发送给服务器,以检查资源是否有更新。 若在协商缓存中服务器确认内容没有更新,则服务器会返回304状态码,浏览器就会使用本地缓存;如果内容更新了,则会返回200状态码和新的资源内容。 3. **预缓存(Pre-Caching)** - Service Workers:通过Service Workers可以拦截网络请求,并动态地缓存或者恢复资源。这允许创建有效的离线体验,并且可以精细控制缓存策略。 4. **内存和硬盘缓存** 浏览器通常将资源缓存在内存或硬盘中: - 内存缓存:缓存存储在内存中,访问速度快,但只在浏览器会话期间有效。 - 硬盘缓存:缓存存储在硬盘上,访问速度慢一些,但即使关闭浏览器后依然可以使用。 举个例子,假设您访问了一个前端的网站,网站的CSS文件设置了强缓存,`Cache-Control`设置为`max-age=3600`,这意味着在接下来的一个小时内,如果您再次访问该网站,浏览器就会直接使用本地缓存的CSS文件,而不需要再次请求服务器,这样就能加快页面的加载速度。 而对于网站的新闻部分,可能会使用协商缓存,每次访问时通过ETag或者Last-Modified信息检查内容是否有更新,以确保用户总是看到最新的内容,同时在内容没有更新的情况下减少不必要的资源传输。
前端2024年6月24日 16:43
什么是同源策略?什么是跨域问题?有什么手段可以解决跨域问题?### 同源策略 同源策略是一种对浏览器发出请求的安全策略。根据这种策略,一个Web页面只能从同一来源(协议,域名和端口都必须相同)获取数据。 ### 跨域问题. 当一个Web页面尝试从不同的源访问资源时,就会出现跨域问题。例如,一个在 www.example1.com 上托管的脚本尝试访问 www.example2.com 上的资源,这就违反了同源策略,所以浏览器会阻止这个请求并产生跨域错误。 ### 解决跨域问题的手段 以下是一些常见的解决跨域问题的方法: 1. **CORS(跨源资源共享)**:CORS是一种让服务器允许来自特定源访问资源的机制。服务器通过设置特定的HTTP头部告诉浏览器哪些Web页面可以访问这些资源。 2. **JSONP(JSON with Padding)**:JSONP是一种通常用于解决跨域数据获取问题的方式。不过,这种方式局限于GET请求,并且安全性较差。 3. **代理服务器**:可以使用服务器端的代理转发请求,因为在服务器端不受同源策略限制。 4. **postMessage API**:使用HTML5引入的 window.postMessage 方法,可以安全地实现跨源通信。 5. **WebSocket协议**:WebSocket是一种建立在TCP协议之上的全双工通信协议,不受同源策略影响。 6. **WebSockets**:WebSockets API 是另一种通信协议,它不受同源策略的影响,可以用于任何地方的通信。 7. **Document.domain+iframe**:基于 document.domain 的跨域方法只适合主域相同的情况,也就是abc.example.com到www.example.com这样的跨域,区域子域和顶级字段相同。
前端2024年6月24日 16:43
JS 如何去除 url 中的#号?如果我们要在JavaScript中去除URL中的 `#` 号以及后面的部分,我们可以使用 `window.location` 对象,具体是 `window.location.href` 属性,再结合 `String` 对象的 `split` 方法。请看以下例子: ```javascript // 假设当前URL为: https://www.example.com/page.html#section1 // 使用 JavaScript 获取当前URL并去除 # 及之后的部分 function removeHashFromUrl() { var currentUrl = window.location.href; var urlWithoutHash = currentUrl.split('#')[0]; window.location.href = urlWithoutHash; // 如果需要导航到去除hash的URL return urlWithoutHash; // 如果只是需要获取新的URL而不导航 } var newUrl = removeHashFromUrl(); console.log(newUrl); // 输出:https://www.example.com/page.html ``` 如果我们是在后端处理URL字符串,比如在Node.js环境或者其他不涉及浏览器的上下文中,我们可以简单地使用字符串处理方法。这里是用Node.js中的JavaScript例子: ```javascript // 假设有一个URL字符串 var url = "https://www.example.com/page.html#section1"; // 去除URL中的 # 及之后的部分 function removeHashFromUrl(url) { return url.split('#')[0]; } var newUrl = removeHashFromUrl(url); console.log(newUrl); // 输出:https://www.example.com/page.html ``` 在Python中处理URL也很简单,我们可以使用内置的 `urlparse`库,这样可以更加优雅地处理复杂的URL。这是一个Python例子: ```python from urllib.parse import urlparse # 假设有一个URL字符串 url = "https://www.example.com/page.html#section1" # 去除URL中的 # 及之后的部分 parsed_url = urlparse(url) new_url = parsed_url.scheme + "://" + parsed_url.netloc + parsed_url.path print(new_url) # 输出:https://www.example.com/page.html ``` 以上提供了去除URL中 `#` 号的几种方法,具体使用哪种取决于具体的应用场景以及开发环境。在前端JavaScript开发中,我们通常可能会涉及到浏览器的 `window.location` 对象,而在服务器端或者其他一些脚本处理中,则可能会使用字符串处理函数或者URL解析库。
前端2024年6月24日 16:43
详细说明浏览器的缓存机制浏览器的缓存机制主要是为了提高网页的加载速度,减少服务器的负载,并优化用户的浏览体验。浏览器缓存可以分为以下几种类型: 1. **强缓存(HTTP Cache Control)** 强缓存不会向服务器发送请求,直接从缓存中读取资源。这是通过设置HTTP响应头中的 `Cache-Control`和 `Expires`实现的。 - `Cache-Control`: 这个响应头可以设置多个值,比如: - `max-age=xxx`:表示资源在xxx秒后过期。 - `no-store`:不允许缓存,每次都要向服务器请求。 - `no-cache`:资源不会被缓存,每次都会发请求到服务器验证资源是否有更新。 - `Expires`: 这是一个绝对时间,表示资源的过期时间。 2. **协商缓存(Validation Cache)** 当强缓存失效后,浏览器会向服务器发送请求,询问资源是否有更新。这是通过 `Last-Modified/If-Modified-Since`和 `ETag/If-None-Match`这两对HTTP头实现的。 - `Last-Modified/If-Modified-Since`: 服务器响应时通过 `Last-Modified`标识资源最后修改时间,浏览器下次请求时带上 `If-Modified-Since`,服务器比较后如果没有变化则返回304状态码,浏览器继续使用缓存。 - `ETag/If-None-Match`: `ETag`是资源的一个唯一标识,类似于指纹。浏览器在请求时带上 `If-None-Match`,服务器对比ETag,如果没有变化则返回304状态码,浏览器继续使用缓存。 3. **Web Storage(本地存储)** 包括 `localStorage`和 `sessionStorage`,它们提供了在客户端存储键值对数据的能力。`localStorage`数据在浏览器关闭后依然存在,而 `sessionStorage`的数据在页面会话结束时被清除。 4. **IndexedDB** 是一种在浏览器中保存大量结构化数据的方式,可以创建、读取、遍历和搜索数据库中的记录。IndexedDB操作基于事件响应,与Web Storage相比,它可以提供更复杂的数据操作功能。 5. **Service Workers** Service workers可以拦截请求,并可以使用缓存API来管理请求的响应。开发者可以编写自己的缓存策略,例如,当网络不可用时,可以从缓存中提供备份内容。 举个例子,假设用户第一次访问一个网页,浏览器会下载所有资源,并按照HTTP头信息决定哪些资源应当被缓存。当用户再次访问这个网页时,如果相关资源具备有效的强缓存设置,浏览器会直接从缓存中加载资源,不经过服务器请求,这样可以极大提高页面加载速度。如果强缓存过期,浏览器会使用协商缓存机制与服务器通信,确认资源是否更新,从而决定是重新下载资源,还是继续使用缓存版本。