广州4399一面面试

令人窒息的面试过程,我发现我还不能够掌握面试的主动权,可能就是没有一个点是可以值得深挖的吧,以至于不能长久的去讨论。发现自己可能知道如何引导,但是具体的展开还是需要多学习。

1、http的状态码
  • 1XX:指示信息–表示请求已经被接受,继续处理
  • 2XX:成功–表示已经被成功接受、理解、接受
  • 3XX:重定向–要完成请求必须进行更进一步的操作
  • 4XX:客户端错误–请求有语法错误或请求无法实现
  • 5XX:服务器错误–服务器未能实现合法的请求
2、cookie、session

Cookies是通过在客户端记录信息确认用户身份,Session通过在服务器端记录信息来确认用户信息。

字段名 含义
name 字段为一个cookie的名称
value 字段为一个cookie的值
domain 字段为可以访问此cookie的域名,非顶级域名,是二级域名或三级域名
path 字段为可以访问此cookie的页面路径。
expires/Max-Age 此字段为cookie的超时事件,到此之后,此cookie失效,不设置的话默认值是Session(即整个浏览器关闭后)
size 此cookie的大小
http 字段为httponly属性,如果此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie
secure 字段cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie
3、跨域的解决方案
1
2
3
4
5
6
7
8
9
10
//在www.a.com域名写下如下代码,去请求www.b.com域名的数据
<script>
var script = document.creatElement('script');
script.type = 'text/javascript';
script.src = 'http://www.b.com/getdata?callback=demo';

function demo(res){
console.log(res);
}
</script>
  • JSONP:利用动态脚本的src属性,变相地发送了一个http://www.b.com/getdata?callback=domo。这时候,b.com页面接受到这个请求时,如果没有JSONP,会正常返回json的数据结果,像这样:{msg:'helloworld'},而利用JSONP,服务端会接受这个callback参数,然后用这个参数值包装要返回的数据:demo({msg:helloworld});到这个时候,如果a.com的页面上正好有一个demo函数
1
2
3
function demo(res) {
console.log(res);
}

当远程数据一返回的时候,随着动态脚本的执行,这个demo函数就会被执行。

  • CORS跨域资源共享:跨域资源共享(CORS)是一种机制,它使用额外的HTTP头来告诉浏览器,让运行在一个与origin上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域或端口请求资源时,资源会发起一个跨域的HTTP的请求。应该算是现在比较推荐的跨域解决方案。

    • 现在浏览器将CORS的请求分成两类:简单请求非简单请求
    • 同时满足以下条件的才是简单请求
    请求方式 HTTP的头信息不超过字段
    HEAD Accept
    GET Accept-Language
    POST Content-Language
    Content-Type(application/x-www-form-urlencoded、mulitipart/form-data、text/plain)

    非简单请求会发出一次预检测请求,返回码是204,预检测通过才会真正发出请求,这才返回200。这里通过前端发请求的时候增加一个额外的headers来触发非简单请求。

    • 进行带有身份凭证的CORS请求

      • 默认情况下的跨域请求都是不会把cookie发送给服务器的,在需要发送的情况下,如果是xhr,那么需要设置xhr.withCredentials=true
      • 如果是采用fetch获取的话,那么需要在request里面设置credential:’include’,
      • 但是如果服务器在预请求的时候没返回Access-Control-Allow-Crenditials:ture的话,那么在实际请求的时候,cookie是不会被发送给服务器端的,要特别注意对于简单的get请求,不会有预请求的过程
      • 那么在实际请求的时候,如果服务器没有返回Access-Control-Allow-Crenditial:true的话那么相应结果浏览器也不会交给请求者。
    • 对于附带身份凭证的请求,服务器不得设置Access-Control-Allow-Origin的值为“*”。这是因为请求的首部中携带了Cookie信息,如果Access-Control-Allow-Origin的值为“*”,请求将会失败。而将Access-Cotrol-Allow-Origin的值设置为http://www.a.com,则请求将成功执行。

    • HTTP响应首部字段

      字段 意义
      Access-Control-Allow-Origin <origin>|*
      Access-Control-Expose-Headers 头让服务器把允许浏览器访问的头放入白名单
      Access-Control-Max-Age 头指定了preflight请求的结果能够被缓存多久
      Access-Control-Allow-Credentials 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容
      Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求所允许使用的HTTP方法。(GET/PUT/POST/DELETE)
      Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段(Content-Type)
4、清除浮动

清除浮动的目的是什么,即要解决什么样的问题。一个浮动的例子。

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
27
28
29
30
<div class="topDiv">
<div class="floatDiv">float left</div>
<div class="textDiv">...</div>
</div>
<div class="bottomDiv">...</div>

<style>
.topDiv {
width: 500px;
border: 2px solid black;
}
.floatDiv {
width: 100px;
height: 100px;
border: 2px dotted red;
color: red;
margin: 4px;
float: left;
}
.bottomDiv {
width: 500px;
height: 100px;
margin: 5px 0;
border: 2px dotted black;
}
.textDiv {
color: blue;
border: 2px solid blue;
}
</style>

会看到float会覆盖在两个div上。

同时还可能会出现的问题有:

  • 文字围绕哦浮动元素排版,但我们可能希望文字(.textDiv)排列在浮动元素下方,或者我们并不希望.textDiv两边有浮动元素存放。
  • 浮动元素排版超出其父元素(.topDiv),父元素的高度出现了坍塌,若没有文字高度的支持,不考虑边框,父级元素高度会坍塌成零。
  • 浮动元素甚至影响到了其父元素的兄弟元素(.bottomDiv)的排版。因为浮动元素脱离了文档流,.bottomDiv在计算元素位置的时候会忽略其影响,紧接着上一个元素的位置继续排列。

解决第一个问题,需要清除.textDiv周围的浮动,而解决第二个问题,因为父元素位置只受父元素位置的影响,就需要第一种方法将父元素的高度撑起来,将浮动元素包裹其中,避免浮动元素影响父元素外部的元素排列。

清除浮动的方式

  • 在父元素结束标签之前插入清除浮动的块级元素
1
2
3
4
5
.textDiv{
color:blue;
border:2px solid blue;
clear:left;
}

通过上面的样式,.textDiv告诉浏览器,我的左边不允许有浮动的元素存在,请清除掉我左边的浮动元素。然而,因为浮动元素(.floatDiv)位置已经确定,浏览器在计算.textDiv的位置时,为满足其需求,将textDiv渲染在浮动元素下方,保证了.textDiv左边没有浮动元素。同时可以看出,父元素的高度也被撑起来了,其兄弟元素的渲染也不再受到浮动的影响,这是因为.textDiv仍然在文档流中,它必须在父元素的边界内,父元素只有增加其高度才能达到其目的,哪边不允许有浮动,clear就是对应方向的值。

但是如果任然是上面的这个例子,我们将浮动元素和上面一个的文本块交换位置以后,无论文本块如何应用清除浮动,情况都是会影响下面父亲的兄弟块。

那么可以在浮动元素的后面插入一个空白元素块,并且clear:both这和之前的清除原理一致。

  • 利用伪元素(clearfix)

在HTML结构如下,为了惯例相符,在.topDiv的div上再添加一个clearfix类:

1
2
3
4
5
6
7
8
9
10
11
12
<div class="topDiv clearfix">
<div class="floatDiv">float left</div>
<div class="textDiv">...</div>
</div>
<div class="bottomDiv">...</div>

.clearfix:after {
content: '.';
height: 0;
display:block;
clear:both;
}

该样式在clearfix,即父元素的最后,添加了一个:after伪元素,通过清除伪元素的浮动,达到称起父元素高度的目的。注意到该元素的display值为block,即它是一个不可见的块级元素,他们的底层本质是一样的。

  • overflow清除浮动

    1
    2
    3
    4
    5
    6
    7
    8
    .topDiv {
    width: 500px;
    padding: 4px;
    border: 2px solid black;

    // 区别在这里
    overflow: auto;
    }

仅仅只在父元素上添加了一个值为auto的overflow属性,父元素的高度立刻被撑起,将浮动元素包裹在内。看起来,浮动被清除了,浮动不再会影响到后续元素的渲染。其实,这里的overflow值,还可以是除了“visible”之外的任何有效值,它们都能达到撑起父元素的高度,清除浮动的目的,不过,有的值可能会带来副作用,比如,scrool的值会导致滚动条始终可见,hidden会使得超出边框部分不可见等。那他们是如何清除浮动的呢?

要讲清除这个解决方案的原理,有一个概念始终是绕不过去,那就是格式化上下文(BFC),然而这又是一个要讲清楚这个解决方案的原理

MDN上对BFC的定义:块级格式化上下文是CSS可视化渲染的一部分。它是一块区域,规定了内部块盒的渲染方式,以及浮动相互之间的影响关系。

块级格式化上下文有以下几个特点:

  • BFC像一道屏障,隔离出BFC的内部和外部,内部和外部区域的渲染相互之间互不影响。BFC有自己的一套内部子元素的渲染规则,不影响外部渲染,也不受外部渲染影响。
  • BFC的区域不会和外部浮动盒子的外边距区域发生叠加。也就是说,外部任何浮动元素区域和BFC区域是泾渭分明的,不可能重叠。
  • BFC在计算高度的时候,内部浮动元素的高度也是要计算在内的。也就是说,内部只有一个浮动元素也是不发生坍塌,高度始终大于等于浮动元素的高度的。
  • HTML结构中,当构建BFC区域的元素紧接着一个浮动盒子时,即,是该浮动盒子的兄弟节点,BFC区域会首先尝试在浮动元素旁边渲染,如果宽度不够,就在浮动元素的下边渲染。

形成BFC的条件:

  • 根元素或者包含根元素
  • 绝对定位元素:position为absolute或fixed
  • 行内块元素:display:inline-block
  • 表格单元格:display:teble-cell,html表格表单默认为该值
  • 表格标题:元素的display为table-caption,html表格标题默认为该值
  • overflow:不为visible
5、手写一个抽奖展示页面
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>抽奖展示页</title>
<style>
#demo {
list-style: none;
height: 65px;
overflow: hidden;
}
</style>
</head>

<body>
<h1>最近通知</h1>
<ul id='demo'>
<li>恭喜罗X获得特等奖 别墅一套</li>
<li>恭喜张4获得一等奖 跑车一辆</li>
<li>恭喜张5获得二等奖 华为手机一部</li>
<li>恭喜张6获得二等奖 华为手机一部</li>
<li>恭喜张7获得三等奖 小米手机一部</li>
<li>恭喜张8获得三等奖 小米手机一部</li>
<li>恭喜张9获得三等奖 小米手机一部</li>
</ul>

</body>
<script>
function sroll(id, delay = 500){
if (!id) {
throw new Error("选择器不存在");
}
let timer = null;
let ele = document.getElementById(id);
let c = function () {
// if (timer) {
// clearInterval(timer)
// }
ele.onmouseover = function () {
clearInterval(timer);
}
ele.onmouseout = function () {
c();
}
/*
scrollHeigh、只读、文档内容的实际高度,包括超出视窗的溢出部分
scrollTop滚动条滚动距离
clientHeight窗口可视范围高度,包含padding,但不包含border、水平滚动条、margin元素的高度
offsetHeight`只读`是包含padding、border、水平滚动条,但不包括margin

*/

if (ele.scrollHeight >= ele.offsetHeight) {
timer = setInterval(() => {
if (ele.scrollTop >= ele.scrollHeight) {
ele.scrollTop = 0;
} else {
if (ele.scrollTop >= ele.children[0].offsetHeight) {
ele.append(ele.children[0]);
}
ele.scrollTop++;
}
}, delay);
}
}
return c;

}
let callback = sroll('demo')
callback();
</script>

</html>
6、阻止事件冒泡
  • 在W3C中,使用event.stopPropagation()方法
  • 在IE下设置event.cancelBubble = true;
7、使得p变得可编辑

可以使用contenteditable = true,

如果还需要复制粘贴字段长度正常,可以把值修改成”plaintext-only”

8、readyState几个数字的含义
数字 含义
0 代表未初始化,还没有调用open方法
1 代表正在加载。open方法已被调用,但send方法还没有被调用
2 代表方法已经加载完毕。send已被调用,请求已经开始,但当前的状态和http的请求头未知。
3 代表交互中。服务器正在发送相应。已经接受到了部分数据,因为响应及http的头不全,这时通过responseBody和responseText获取部分数据会出现错误。
4 代表完成。响应发送完毕。
9、解决0.1+02==0.3问题的几种方法
1
2
3
4
5
6
7
8
9
10
11
12
function numbersequal(a,b){ return Math.abs(a-b)<Number.EPSILON;
}
var a=0.1+0.2, b=0.3;
console.log(numbersequal(a,b)); //true


Number.EPSILON=(function(){ //解决兼容性问题
return Number.EPSILON?Number.EPSILON:Math.pow(2,-52);
})();
//上面是一个自调用函数,当JS文件刚加载到内存中,就会去判断并返回一个结果,相比if(!Number.EPSILON){
// Number.EPSILON=Math.pow(2,-52);
//}这种代码更节约性能,也更美观

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!