乐闻世界logo
搜索文章和话题

前端面试题手册

PNG,GIF,JPG 的区别及如何选

GIF8 位像素,256 色无损压缩支持简单动画支持 boolean 透明适合简单动画JPEG颜色限于 256有损压缩可控制压缩质量不支持透明适合照片PNG有 PNG8 和 truecolor PNGPNG8 类似 GIF 颜色上限为 256,文件小,支持 alpha 透明度,无动画适合图标、背景、按钮
阅读 26·2024年6月24日 16:43

Form 表单可以执行跨域请求吗?

HTML表单(form)是可以执行跨域请求的。在Web开发中,跨域请求指的是从一个源(domain、协议、端口)发起的请求试图获取另一个源上的资源。通常,出于安全考虑,浏览器会实施同源策略(Same-Origin Policy),这意味着如果使用XMLHttpRequest或Fetch API来发起Ajax请求,那么请求通常会受到限制,除非目标服务器明确允许跨源资源共享(CORS,Cross-Origin Resource Sharing)。但是,HTML表单不受同源策略的限制,因此可以向任何URL发起POST或GET请求,即使这个URL指向的是另一个域。当表单提交时,浏览器会将用户输入的数据作为请求参数发送到表单的 action属性所指定的URL。不过,使用表单进行跨域提交时,浏览器会导航到响应页面,也就是说用户的当前页面会被新页面替换。下面是一个简单的表单跨域请求的例子:<form action="https://example.com/api/submit" method="POST"> <input type="text" name="username" value="User"> <input type="text" name="password" value="Pass"> <input type="submit" value="Submit"></form>在此示例中,表单数据将提交给位于 example.com域的服务器,即使表单所在的HTML页面可能托管在不同的域上。当用户点击提交按钮时,浏览器会将表单数据作为POST请求的一部分发送到 example.com。需要注意的是,即使表单可以跨域提交,服务端仍然需要处理来自不同源的请求。此外,跨域表单提交不会提供Ajax那样的客户端JavaScript接口来访问响应内容,除非服务器在响应中包含适当的CORS头部信息。
阅读 63·2024年6月24日 16:43

介绍下表单提交,和 formData 有什么关系

FormData主要有两个用途:表单序列化将form表单元素的name与value进行组合,实现表单数据的序列化异步上传文件 使用步骤:创建formData对象 const formData = new FormData()初始化: new FormData(form元素)FormData 对象操作方法get(key)与getAll(key)来获取相对应的值append(key,value)在数据末尾追加数据set(key, value)来设置修改数据has(key)来判断是否存在对应的key值delete(key)可以删除数据
阅读 39·2024年6月24日 16:43

什么是 web 语义化,有什么好处

什么是 Web 语义化Web 语义化是指通过 HTML 标记表示页面包含的信息,包含了 HTML 标签的语义化和 css 命名的语义化。HTML 标签的语义化通过使用包含语义的标签(如 h1-h6)恰当地表示文档结构 。CSS 命名的语义化 为 html 标签添加有意义的 class,id 补充未表达的语义,如通过添加符合规则的 class 描述信息。 Web 语义化的好处需要语义化的主要理由有以下几点:去掉样式后页面呈现清晰的结构盲人使用读屏器更好地阅读搜索引擎更好地理解页面,有利于收录便团队项目的可持续运作及维护
阅读 38·2024年6月24日 16:43

JavaScript 执行过程分为哪些阶段?

JavaScript 的执行过程大致可以分为以下几个阶段:1. 解析(Parsing)在这一阶段,JavaScript 引擎会读取源代码,并将其解析成抽象语法树(AST)。抽象语法树是一种深层次的、结构化的代码表达方式,能够以树形结构表现代码中的每个语句、表达式等元素。解析过程中,如果遇到语法错误,会抛出错误,停止进一步执行。2. 编译(Compilation)JavaScript 引擎(如V8)通常会将解析后的代码进行即时编译(JIT)。编译器会先生成字节码,这是一种低级的、比源代码更接近机器语言的代码。随后根据程序的执行情况,编译器可能会把热点代码(经常执行的代码)编译成优化的机器码,提高执行效率。3. 执行(Execution)编译后得到的字节码或机器码被送到 JavaScript 引擎的执行环境中执行。在执行过程中,会进入下面的子阶段:创建执行上下文(Execution Context):首先会创建全局执行上下文,随后每当调用一个函数时,就会为该函数创建一个新的执行上下文。执行上下文包括变量对象、作用域链和 this 引用等信息。变量提升(Hoisting):在执行代码前,函数声明和变量(声明)会被提升到它们各自的执行上下文的顶部。变量会初始化为 undefined,而函数则会完整地提升。执行代码(Running Code):按照执行上下文中的代码逐行执行,进行变量赋值、函数调用等。垃圾回收(Garbage Collection):在执行过程中,引擎会进行内存管理,自动释放那些不再被需要的内存空间。4. 优化(Optimization)在代码执行的过程中,某些代码可能会被执行多次,引擎会尝试对这些频繁执行的代码进行优化。例如,在V8引擎中,有一个称为“TurboFan”的优化编译器,它可以根据代码执行的特点对代码进行优化,提高性能。如果优化假设失败了(即出现了“去优化” deoptimization),引擎还可以将代码回退到一个较少优化的版本。5. 回收(Deoptimization & Garbage Collection)对于那些不再需要的数据和优化,JavaScript 引擎会进行去优化和垃圾回收,以保证内存的高效使用。例子:假设我们有这样一个简单的 JavaScript 函数:function sum(a, b) { return a + b;}let result = sum(5, 3);首先,该函数会被解析成 AST。然后,它可能会被编译成字节码,当我们调用 sum(5, 3) 时,会创建一个新的执行上下文,包含 a 和 b 的参数以及任何局部变量。在这个上下文中,a 和 b 被赋予了值 5 和 3,函数执行,并返回结果 8。这个过程中可能还包括了对 sum 函数的优化,如果函数被频繁调用。最后,当执行上下文离开作用域,如果没有其他引用指向其中的数据,垃圾回收器最终会清理掉这些对象。
阅读 23·2024年6月24日 16:43

JavaScript 为什么要区分微任务和宏任务?

JavaScript 区分微任务(microtasks)和宏任务(macrotasks)主要是为了有效地管理异步操作的执行时机和顺序。这两种类型的任务允许 JavaScript 引擎维持一个控制异步操作何时何地执行的精细化调度机制。宏任务 (Macrotasks)宏任务通常是浏览器的主要任务,包括但不限于:setTimeoutsetIntervalI/O 操作UI 渲染事件处理(如点击、滚动事件)每次执行栈为空时,事件循环都会从任务队列中取出一个宏任务执行。微任务 (Microtasks)微任务通常是需要快速响应的任务,执行时机在每个宏任务之后,以及JavaScript执行环境准备好以后。微任务包括:Promise 回调(例如.then、.catch和.finally)MutationObserver 的回调queueMicrotask函数执行顺序在每个宏任务执行完毕后,在执行下一个宏任务之前,JavaScript 引擎会处理所有队列中的微任务。这意味着微任务总是在当前宏任务结束和下一个宏任务开始之间执行,并在新的UI渲染前完成。这样可以确保异步操作的快速响应,同时因为微任务的延迟更小,所以适合高优先级的任务。为什么区分区分微任务和宏任务的原因包括:性能优化: 通过微任务,JavaScript 可以在不影响用户界面渲染的情况下,快速执行简单的操作,如承诺的解决。这提高了应用程序的响应速度和性能。控制异步操作顺序: 微任务和宏任务的区分允许开发者控制异步操作的执行顺序。例如,一个由Promise产生的微任务可以确保其在下次UI渲染之前解决,而setTimeout可能会推迟到下一个宏任务。避免阻塞: 对于需要快速执行的代码,使用微任务可以避免阻塞宏任务队列,这有助于避免长时间运行的任务阻塞UI更新。示例假设我们有以下代码:console.log('宏任务开始');setTimeout(() => { console.log('宏任务');}, 0);Promise.resolve().then(() => { console.log('微任务');});console.log('宏任务结束');执行顺序会是这样的:打印"宏任务开始"宏任务结束时,设置了一个setTimeout打印"宏任务结束"当前宏任务已结束,开始执行微任务队列中所有任务打印"微任务"微任务队列为空,开始下一个宏任务打印"宏任务"通过这个例子,我们可以看到微任务总是在当前执行栈清空后立即执行,而宏任务的执行则可能会因为任务队列中的其他宏任务而延迟。这种机制允许JavaScript有效地处理异步事件,同时保持对执行顺序的细粒度控制。
阅读 42·2024年6月24日 16:43

jsonp 为什么不支持 post 方法?

JSONP(JSON with Padding)是一种利用<script>标签不受同源策略限制的特性来实现跨源请求的技术。因为<script>标签的初衷是加载静态的JavaScript文件,所以<script>标签仅支持GET方法来请求资源,它并不支持POST方法。这就是为什么JSONP不支持POST方法的根本原因。当使用JSONP进行通信时,您会将请求参数包含在URL中,并通过动态创建<script>标签的方式将其发出。服务器接收到GET请求后,将数据包裹在一个函数调用中,并将其作为响应返回。客户端定义好回调函数后,这段包裹着JSON数据的JavaScript被执行,回调函数便会被调用并处理返回的数据。例如,假设您的页面需要从http://example.com获取一些用户数据,您可能会发送如下的JSONP请求:<script type="text/javascript"> // 定义回调函数 function handleResponse(data) { console.log('Received data:', data); }</script><script type="text/javascript" src="http://example.com/data?callback=handleResponse"></script>服务器端需要接收到callback参数后,把数据包装在该函数调用中:// 服务器端响应handleResponse({ "user": "Alice", "age": 25 });如上所述,JSONP请求的本质是一个GET请求,它是通过<script>标签的src属性来发起的。因此,它不能使用POST方法,后者通常用于传输大量数据或者发送需要安全传输的数据。如果您需要进行跨域的POST请求,可以考虑使用更现代的技术,如CORS(跨源资源共享),它允许在各种HTTP方法中使用跨源请求,同时提供了更好的安全性。
阅读 21·2024年6月24日 16:43

Ajax 如何处理请求跨域问题?CORS 如何设置?

Ajax 处理请求跨域问题Ajax(Asynchronous JavaScript and XML)本身是不支持跨源请求的,这是因为浏览器出于安全考虑实施的同源策略(Same-Origin Policy)。同源策略限制了来自不同源的文档或脚本对当前文档读取或设置某些属性的能力。不过,有几种方法可以绕过这个限制来实现跨源请求:JSONP(JSON with Padding):这是一种老的技巧,它利用 <script>标签不受同源策略限制的特点来进行跨域请求。服务器返回的响应拼接一个函数调用作为JavaScript代码。这种方法的缺点是它只能用于GET请求,并且存在一定的安全隐患。CORS(Cross-Origin Resource Sharing):这是现在推荐的方法,它允许服务器显式地指定哪些源可以访问该服务器上的资源。CORS是一个 W3C 标准,它通过在服务器上设置特定的HTTP头来工作。代理服务器:使用一个服务器充当中间人的角色,接受来自客户端的跨源请求,然后转发请求到目标服务器。代理服务器接收到响应后,再将数据返回给客户端。这种方法需要额外的服务器端配置。WebSockets: WebSockets提供了一个全双工的通信渠道,可以在浏览器和服务器之间建立持久连接。虽然WebSocket协议与HTTP不同,但它可以绕过同源策略,从而实现跨域通信。CORS 设置当你控制服务器时,可以通过设置HTTP响应头来启用CORS。这些头部主要包括:Access-Control-Allow-Origin: 指定了哪些网站可以参与跨域资源共享。例如,设置为 *代表允许所有域进行跨域请求,但出于安全考虑通常会指定明确的域名。Access-Control-Allow-Methods: 指定了允许的HTTP请求方法,如 GET, POST, PUT, DELETE, OPTIONS等。Access-Control-Allow-Headers: 在实际请求中允许自定义的HTTP头部字段列表。Access-Control-Allow-Credentials: 表示是否允许发送Cookie。如果服务器端设置了这个值为 true,那么前端请求的时候也必须将 withCredentials属性设置为 true。Access-Control-Expose-Headers: 允许客户端访问的服务器白名单头部字段。Access-Control-Max-Age: 表明在多少秒内,不需要再发送预检验请求(对于某一资源的预检请求结果的有效期)。下面是一个简单的例子,展示了如何在Node.js的Express框架中设置CORS响应头:const express = require('express');const app = express();app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'https://example.com'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization'); res.header('Access-Control-Allow-Credentials', true); if (req.method === 'OPTIONS') { res.header('Access-Control-Max-Age', '86400'); return res.status(200).send(); } next();});// 你的其他路由和逻辑app.listen(3000, () => { console.log('Server running on port 3000');});
阅读 27·2024年6月24日 16:43

base64 为什么能提升性能?

Base64编码通常不是直接用来提升性能的,而是用来确保二进制数据可以通过仅支持文本格式的传输层安全地传输。Base64将二进制数据编码为ASCII字符串,这使得它可以在不支持二进制数据的系统(如电子邮件)中传输。虽然Base64编码的数据比原始二进制数据大约增加了33%,但在某些情况下,它可以间接地提升性能:减少HTTP请求:在Web开发中,Base64编码通常用于将小的图片或其他文件直接嵌入到HTML或CSS中。这样做的好处是可以减少浏览器发起的HTTP请求的数量,因为所有的资源都包含在了主文档中。少了额外的请求,网页加载时间就会缩短,间接提高了用户体验和性能。举个例子,如果一个网页中有多个小图标,通常的做法可能是每个图标一个HTTP请求来获取图像文件。如果将这些图标的图片用Base64编码后嵌入到CSS中,就可以将多个HTTP请求合并为一个请求,从而减少了服务器的请求负载和网络延迟,提高了页面的加载速度。数据URI方案:Base64编码可以使用数据URI方案在Web页面中直接嵌入图像数据,这样可以避免服务器配置对小文件的较慢响应时间。服务器对小文件的处理往往不如大文件高效,因为涉及到磁盘I/O等开销。通过避免这些小文件请求,可以在服务器端节省资源,从而提升性能。安全和兼容性:有些系统不支持二进制数据的传输,或者在传输过程中可能会因为某些字符(如NUL byte)的存在而出现问题。在这种情况下,Base64编码提供了一种可靠的方法来处理和传输数据,避免了潜在的数据损坏和传输错误,从而确保系统的顺畅运行和性能。总之,Base64编码本身增加了数据量,理论上会降低传输效率,但通过减少HTTP请求的数量、充分利用缓存、避免小文件请求开销以及提高数据的安全性和兼容性,它可以在特定场景下间接提升系统的整体性能。
阅读 68·2024年6月24日 16:43

如何去除 url 中的#号?

如果我们要在JavaScript中去除URL中的 # 号以及后面的部分,我们可以使用 window.location 对象,具体是 window.location.href 属性,再结合 String 对象的 split 方法。请看以下例子: // 假设当前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例子:// 假设有一个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例子: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.pathprint(new_url) # 输出:https://www.example.com/page.html以上提供了去除URL中 # 号的几种方法,具体使用哪种取决于具体的应用场景以及开发环境。在前端JavaScript开发中,我们通常可能会涉及到浏览器的 window.location 对象,而在服务器端或者其他一些脚本处理中,则可能会使用字符串处理函数或者URL解析库。
阅读 34·2024年6月24日 16:43