前端经典面试题整理

204 阅读15分钟

1.options请求的作用?

HTTP OPTIONS请求是一种用于查询给定的URL或服务器支持的通信选项的方法。客户端可以用这个方法指定一个URL,或者用星号( * )来指代整个服务器。

HTTP OPTIONS请求的作用有以下几点:

  • 识别允许的请求方法:客户端可以用HTTP OPTIONS请求来询问服务器支持哪些请求方法,比如GET, POST等。服务器会在响应中包含一个Allow头,列出允许的方法。
  • 预检请求(preflight request):在跨域资源共享(CORS)中,客户端在发送实际请求之前,会先发送一个HTTP OPTIONS请求,来检查服务器是否接受这个请求。这个预检请求会包含一些Access-Control-Request-*头,来说明实际请求的方法、头部和来源等信息。服务器会在响应中包含一些Access-Control-Allow-*头,来表示是否允许这个跨域请求。
  • 获取API信息:客户端可以用HTTP OPTIONS请求来获取服务器提供的API的信息,比如支持的参数、格式、版本等。服务器可以在响应中包含一些自定义的头部或者正文,来描述API的细节。

2. http 缓存

HTTP缓存是一种网络技术,它可以在客户端或服务器端存储HTTP请求的响应,并在后续的请求中重复使用这些响应,以提高网页的加载速度和性能。

HTTP缓存的作用有以下几点:

  • 减少网络流量和带宽消耗:通过使用缓存中的响应,可以避免重复从服务器获取相同的资源,从而节省网络资源和成本。
  • 降低服务器负载和延迟:通过使用缓存中的响应,可以减少服务器处理请求的次数和时间,从而提高服务器的效率和响应速度。
  • 提升用户体验和满意度:通过使用缓存中的响应,可以加快网页的加载时间和渲染速度,从而提高用户的感知和满意度。

HTTP缓存可以分为两大类,强制缓存(也称强缓存)和协商缓存。

  • 强制缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的Network选项中可以看到该请求返回200的状态码,并且size显示from disk cache或from memory cache两种(灰色表示缓存)。 强制缓存由Cache-Control或Expires标头控制,它们指定了资源的最大有效期(max-age)或过期时间(expires)。如果资源在有效期内或未过期,则可以直接使用缓存中的响应。
  • 协商缓存:需要向服务器发送请求,询问服务器是否有更新的资源,如果有,则返回新的资源和200的状态码;如果没有,则返回304的状态码,并告知客户端使用缓存中的响应。协商缓存由Last-Modified或ETag标头控制,它们分别表示资源的最后修改时间或唯一标识符。客户端可以通过If-Modified-Since或If-None-Match标头将这些值发送给服务器,让服务器判断资源是否有变化。

强制缓存的弊端很明显,即每次都是根据时间来判断缓存是否过期;但是当到达过期时间后,如果文件没有改动,再次去获取文件就有点浪费服务器的资源了

3. http和https协议比较,https加密算法(ssl/tls) , 响应速度分析

HTTP and HTTPS are both methods for transferring data over the internet, but they have some significant differences in terms of security, performance, and usage.

  • Security: HTTP is an unencrypted protocol, which means that the data sent and received between the client and the server is in plain text and can be intercepted or modified by attackers. HTTPS is an encrypted protocol, which means that the data is protected by SSL/TLS certificates and algorithms, making it harder for attackers to access or tamper with the data. HTTPS also provides authentication for the server, ensuring that the client is communicating with the intended website.
  • Performance: HTTP is faster than HTTPS in terms of connection establishment, because HTTP only requires a TCP three-way handshake, while HTTPS requires an additional SSL/TLS handshake. However, HTTPS can be faster than HTTP in terms of data transmission, because HTTPS can use newer protocols such as HTTP/2 and QUIC, which support features such as multiplexing, compression, prioritization, and encryption.
  • Usage: HTTP is suitable for transmitting static or public content, such as images, videos, or web pages that do not contain sensitive information. HTTPS is suitable for transmitting dynamic or private content, such as user credentials, payment details, or personal data. HTTPS is also preferred by search engines and browsers, as they consider it a ranking factor and a trust indicator.

4.关于跨域 什么是跨域,如何处理跨域(jsonp技术)cors和同源政策 代理的作用

4.1 同源策略和跨域资源共享

跨域是指浏览器不能执行其他网站的脚本,是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。

同源策略要求两个网页的协议、域名和端口都完全相同,才能相互访问彼此的资源。如果不满足这些条件,就会发生跨域,浏览器会拒绝或拦截这些请求。¹²

跨域的目的是为了保护用户的隐私和安全,防止恶意网站获取或修改用户的数据。例如,如果您登录了淘宝网,但又访问了一个恶意网站,如果没有跨域限制,那么恶意网站就可以通过JavaScript读取或操作您的淘宝账户信息,这样就会造成严重的后果。¹²

跨域问题有多种解决方法,常见的有以下几种:

  • JSONP:JSONP是一种利用
  • CORS:CORS是一种利用HTTP头部来实现跨域请求的方法。它需要服务器在响应头中添加一些允许跨域访问的字段,如Access-Control-Allow-Origin等,并在客户端使用XMLHttpRequest或Fetch API来发送请求。
  • 代理服务器:代理服务器是一种利用中间服务器来转发跨域请求的方法。它需要在客户端和目标服务器之间设置一个代理服务器,让客户端向代理服务器发送请求,然后由代理服务器向目标服务器转发请求,并将响应返回给客户端。

4.2 jsonp技术

JSONP是一种在JavaScript程序中请求不同域名的服务器数据的方法。JSONP绕过了大多数网页浏览器的限制,即访问网页必须在同一域名下。

JSONP的原理是,利用网页浏览器可以加载不同域名的

例如,如果您想要从(server.example.com/Users/1234) 这个地址获取一个人的信息,您可以在网页上定义一个函数parseResponse(),然后创建一个<script>元素,将地址加上一个回调参数callback=parseResponse作为源地址。如下所示:

<script src="[5](http://server.example.com/Users/1234?callback=parseResponse)"></script>

这样,服务器会返回一个类似于这样的响应:

parseResponse({"Name": "Clem", "Id": 1234, "Rank": 7});

网页浏览器会执行这个函数调用,并将JSON数据作为参数传递给parseResponse()函数。这样,您就可以在函数中使用这些数据了。

JSONP是一种历史悠久的技术,它有一些优点和缺点:

  • 优点:JSONP可以实现跨域数据请求,而不需要服务器支持CORS(跨域资源共享)或其他特殊的设置。JSONP也比XMLHttpRequest对象更兼容一些旧的浏览器。
  • 缺点:JSONP只能使用GET方法发送请求,不能使用POST或其他方法。JSONP也不能处理错误或超时的情况,因为

因此,JSONP已经被现代的跨域技术所取代,如CORS、Fetch API等。

5. css实现超出宽度的内容用省略号显示

white-space CSS属性是一种用于控制元素内部的空白字符(如空格、换行等)的处理方式的属性。它可以设置以下两件事:

  • 是否以及如何折叠空白字符。折叠空白字符是指将多个连续的空白字符合并为一个,或者删除不必要的空白字符。
  • 是否以及如何换行。换行是指当文本超出元素的边界时,是否在合适的位置断开文本,并将其移动到下一行。

white-space CSS属性有以下几种可能的值:

  • normal:这是默认值,表示会折叠空白字符,并且会在必要时换行。
  • nowrap:表示会折叠空白字符,但是不会换行,文本会在同一行显示,直到遇到
    标签或者结束。
  • pre:表示不会折叠空白字符,也不会换行,文本会保留原来的格式,只有在遇到
    标签或者结束时才会换行。这个值类似于HTML中的
    标签。
  • pre-wrap:表示不会折叠空白字符,但是会在必要时换行,文本会保留原来的格式,但是也会根据元素的边界进行自动换行。
  • pre-line:表示会折叠空白字符,并且会在必要时换行,文本会保留原来的换行符,但是也会根据元素的边界进行自动换行。
<div style="white-space: nowrap; width:20; overflow: hidden; text-overflow: ellipsis;">ssssssssssssssssssssssssssson        gthing</div>

显示效果

截屏2023-08-25 23.10.24.png

如果不加white-space: nowrap的话,会在空格处换行,形成这样的效果

截屏2023-08-25 23.13.32.png

6.display:none和visibility:hidden

两者都可以用来隐藏元素,但是它们有一些区别,主要有以下几点:

  • display:none 会让元素完全消失,不占据任何空间,也不影响布局。visibility:hidden 会让元素不可见,但是仍然占据原来的空间,会影响布局。
  • display:none 不是继承属性,如果给父元素设置了 display:none,那么它的子元素也会隐藏。visibility:hidden 是继承属性,如果给父元素设置了 visibility:hidden,那么它的子元素也会隐藏,除非子元素设置了 visibility:visible
  • 给某个元素设置成 display:none 会触发回流(reflow),重新计算布局和渲染。visibility:hidden 只会触发重绘(repaint),不会重新计算布局。 display:none 不会被屏幕阅读器读取,也不会响应鼠标或键盘事件。visibility:hidden 会被屏幕阅读器读取,但是不会响应鼠标或键盘事件。
  • display:none 不支持 CSS3 的过渡(transition)效果。visibility:hidden 支持 CSS3 的过渡效果。

7. css选择器有哪些?优先级是如何计算的

CSS 选择器是一种用来选择 HTML 元素的语法,可以根据元素的名称、属性、类别、状态等条件来指定要应用样式的目标。CSS 选择器有很多种,可以分为以下几类:

  • 基本选择器:根据元素的名称、类别、ID 或通配符来选择元素,例如 p、.center、#runoob、* 等。
  • 属性选择器:根据元素的属性或属性值来选择元素,例如 [type="text"]、[title~=flower]、[lang|=en] 等。
  • 伪类选择器:根据元素的状态或位置来选择元素,例如 :link、:hover、:first-child、:nth-of-type(2) 等。
  • 伪元素选择器:根据元素的部分内容或装饰效果来选择元素,例如 ::first-letter、::before、::selection 等。
  • 组合器:根据元素之间的关系来组合选择器,例如 div p(后代选择器)、div>p(子选择器)、div+p(相邻兄弟选择器)、div~p(一般兄弟选择器)等。

CSS 选择器的优先级是指在多个选择器同时作用于同一个元素时,哪个选择器的样式会生效。CSS 选择器的优先级由以下几个因素决定:

  • 权重:不同类型的选择器有不同的权重,权重越高,优先级越高。一般来说,权重由高到低依次为:内联样式(1000)、ID 选择器(100)、类别/属性/伪类选择器(10)、元素/伪元素选择器(1)、通配符/继承/默认样式(0)。
  • 顺序:当权重相同时,后出现的选择器会覆盖前面的选择器。
  • 重要性:当使用 !important 声明时,该声明会覆盖其他所有声明,除非另一个声明也使用了 !important 并且权重更高或顺序更后

8. <script>, <script async><script defer> 有什么区别

The difference between <script>, <script async> and <script defer> is related to how the browser loads and executes the JavaScript code in the HTML document. Here is a brief summary of each type of script tag:

<script>: The browser will stop parsing the HTML document and fetch the script file synchronously. Then it will execute the script before resuming the parsing. This means that the script will block the rendering of the page until it is finished. This is the default behavior of script tags.

<script async>: The browser will fetch the script file asynchronously, without blocking the parsing of the HTML document. However, as soon as the script is ready, it will pause the parsing and execute the script immediately. This means that the script may execute before or after the document is parsed, depending on the network speed and the size of the script. This attribute is only valid for external scripts.

<script defer>: The browser will also fetch the script file asynchronously, without blocking the parsing of the HTML document. However, unlike async, it will defer the execution of the script until after the document is parsed and before the DOMContentLoaded event. This means that the script will always execute after the document is parsed, and in the same order as they appear in the document. This attribute is also only valid for external scripts.

The choice of which type of script tag to use depends on your needs and preferences. Generally speaking, if your script does not depend on any DOM elements or other scripts, you can use async to improve performance and avoid blocking. If your script depends on some DOM elements but not on other scripts, you can use defer to ensure that it executes after the document is parsed. If your script depends on other scripts or needs to execute in a specific order, you can use either plain script or defer with careful ordering.

9. 箭头函数和普通函数的区别

JavaScript 箭头函数和普通函数的区别是一个很常见的问题,也是一个很重要的知识点。箭头函数是在 ES6 中引入的一种新的函数表达式,它可以让我们用更简洁和优雅的方式来定义函数。但是,箭头函数和普通函数不仅仅在语法上有区别,还有一些其他的特性和用法,需要我们注意和理解。以下是一些主要的区别:

  • 箭头函数没有自己的 this 绑定:在普通函数中,this 变量是根据调用它的对象来确定的,例如 obj.print() 中的 this 就指向 obj。但是,在箭头函数中,this 变量是继承自外层作用域的,也就是说箭头函数没有自己的 this,而是沿着词法作用域链向上寻找最近的一个 this。这样可以避免一些 this 指向错误或混乱的情况,也可以让我们在回调函数或事件处理器中更方便地使用 this。

  • 箭头函数没有自己的 arguments 对象:在普通函数中,arguments 对象是一个类数组对象,它包含了传递给函数的所有参数。我们可以通过 arguments[i] 来访问第 i 个参数,或者通过 arguments.length 来获取参数的个数。但是,在箭头函数中,arguments 对象不存在,如果我们想要使用它,就会报错。如果我们需要获取箭头函数的参数,我们可以使用剩余参数(rest parameter)来代替,例如 (a, b, ...args) => {...}。

  • 箭头函数不能作为构造函数:在普通函数中,我们可以使用 new 关键字来创建一个实例对象,并且该对象会继承该函数的原型(prototype)。但是,在箭头函数中,由于它没有自己的 this 绑定,也没有 prototype 属性,所以它不能作为构造函数来使用。如果我们尝试用 new 来调用箭头函数,就会报错。

  • 箭头函数不能被hoist,意味着它不能在初始前被访问

printName()

console.log("hello")

const printName = () => {
  console.log("i am dillion")
}

上述代码将会报错

10. 给出下方代码的输出并解释原因

console.log('开始');

setTimeout(() => {
  console.log('输出一个信息');
}, 0);

console.log('执行');

new Promise((resolve, reject) => {
  console.log('执行for循环');

  for (var i = 0; i < 100; i++) {
    i == 99 && resolve();
  }

  reject();
})
.then(() => {
  console.log('执行then函数');
})
.catch(() => {
  console.log('catch error');
});

console.log('执行结束');

输出:

开始
执行
执行for循环 
执行结束
执行then函数
输出一个信息

解释:

console.log('开始');
// 1.直接输出 '开始'

setTimeout(() => {
  console.log('输出一个信息');
}, 0);
// 6.setTimeout函数,即使延时为0,也会将其放入到消息队列中并在下一个eventloop中进行处理,
因此这里暂时不进行任何操作,'输出一个信息'会在最后被输出。

console.log('执行');
// 2.直接输出 '执行'

new Promise((resolve, reject) => {
  console.log('执行for循环');
  // 3.直接输出 '执行for循环'
  
  for (var i = 0; i < 100; i++) {
    i == 99 && resolve();
  }

  reject();
})
.then(() => {
  console.log('执行then函数');
  // 4.Promise中的函数会立即被执行,当i的值为99时,执行resolve,状态切换为fulfilled,
  跳出循环后又会执行reject,但是promise的状态无法被改变,
  因此reject无法再把状态变为rejected。函数执行完毕后,执行then,输出 '执行then函数'
})
.catch(() => {
  console.log('catch error');
});
console.log('执行结束');
// 5.直接输出 '执行结束'