1、http请求头中包含哪些内容?
Cache-Control:指定请求和响应遵循的缓存机制
Cookie:HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
Content-Length:请求的内容长度
Content-Type:请求的与实体对应的MIME信息
Date:请求发送的日期和时间
User-Agent:User-Agent的内容包含发出请求的用户信息
Host:指定请求的服务器的域名和端口号
Accept:指定客户端能够接收的内容类型
Accept-Charset:浏览器可以接受的字符编码集。
If-Modified-Since:如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码
If-None-Match:如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变
2、手写一个ajax函数。
function ajax(opt){
// 平稳退化 设置各个参数的默认值
opt = opt || {}
opt.url = opt.url || ''
opt.method = opt.method.toUpperCase() || 'POST'
opt.data = opt.data || null
opt.success = opt.success || function(){}
opt.error = opt.error || function(){}
// 创建网络请求对象
let xml
if(XMLHttpRequest){
xml = new XMLHttpRequest()
}else{
xml = new ActiveXObject('Microsoft.XMLHTTP')
}
// 设置网络请求参数
let params = []
for(let key in opt.data){
params.push(`${key}=${opt.data[key]}`)
}
let postData = params.join('&')
// 发送post请求
if(opt.method.toUpperCase === 'POST'){
xml.open(opt.method, opt.url)
xml.setRequestHeader('content-type', 'xxx;charset=utf-8')
xml.send(postData)
// 发送get请求
}else if(opt.method.toUpperCase === 'GET'){
xml.open(opt.method, opt.url + '?' + postData)
}
// 设置网络请求回调函数
xml.onreadystatechange = function(){
if(xml.readystate == 4 && xml.status == 200){
opt.success(xml.response)
}else{
opt.error()
}
}
}
3、OSI七层参考模型以及各层对应的设备和协议
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
![]()
4、三次握手详细过程
(1)第一次握手:建立连接。客户端发送连接请求报文段,将SYN置1,序列号seq(sequence number)为x;然后,客户端进入SYN_SEND状态,等待服务器的确认。
(2)第二次握手:服务器收到客户端的SYN报文段,ACK置1,确认号ack(acknowledgement number)为x+1;同时,自己发送SYN请求,将SYN置1,序列号seq为y;服务器将上述SYN+ACK报文段一并发送给客户端,然后进入SYN_RECV状态。
(3)第三次握手:客户端收到服务器的SYN+ACK报文段:然后将确认号ack设置为y+1,向服务器发送ACK报文段。这个报文段发送完毕后,客户端和服务器都进入ESTABLISHED状态。
5、CORS(跨域资源共享)如何实现
服务器端声明:
response.setHeader('Access-Control-Allow-Origin','*'); 允许任意网站跨域访问当前服务器
response.setHeader('Access-Control-Allow-Headers','*'); 允许任意网站在发送请求时自定义头信息
response.setHeader('Access-Control-Allow-method','*'); 允许任意网站发送任意种类的请求
6、http无状态协议如何保存用户状态?
HTTP 是一种不保存状态,即无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。
常见的有两种解决方案:基于Session实现的会话保持和基于Cookie实现的会话保持。
1、基于Session实现的会话保持
在会话开始时(客户端第一次向服务器发送http请求),服务器将会话状态保存起来(本机内存或数据库中),然后分配一个会话标识(SessionId)给客户端,这个会话标识一般保存在客户端Cookie中,以后每次浏览器发送http请求都会带上Cookie中的SessionId到服务器,服务器拿到会话标识就可以把之前存储在服务器端的状态信息与会话联系起来,实现会话保持(如果遇到浏览器禁用Cookie的情况,则可以通过url重写的方式将会话标识放在url的参数里,也可实现会话保持)。
2、基于Cookie实现的会话保持
基于Cookie实现会话保持与上述基于Session实现会话保持的最主要区别是前者完全将会话状态信息存储在浏览器Cookie中,这样一来每次浏览器发送HTTP请求的时候都会带上状态信息,因此也就可以实现状态保持。
7、进程和线程
8、闭包的使用举例
9、vue源码中模板解析的实现过程
10、数据类型转化规则
转换为布尔值
转换为false的值:空字符串、0、NaN、null、undefined
转换为数值
转换为0的值:'0'、null、false、空字符串、空数组。(使用Number()去转换undefined会返回NaN)
空对象{}:转换为布尔值等于true,转换为数值等于NaN,转换为字符串等于[object Object]。
空数组[]:转换为布尔值等于true,转换为数值等于0,转换为字符串等于空字符串。
字符串转换为数值
Number:只有当字符串内容恰好为数字格式(包括+、-)时,才会被Number转换为对应格式、十进制的数字('011'转换为11,‘01.1’转换为1.1,'0xf'转换为15),只要字符串中包含非数字字符,就返回NaN。
paeseInt:忽略最前面的空格,其后的第一个字符如果不是数值或+-,立刻返回NaN;否则,将开头的数值部分作为一个整体返回。(123blue会返回123;22.5会返回22;red999会返回NaN,'0xf'会返回15。)
注:1、parseInt和Number都能识别表示进制的字符如‘0x’,最终返回的结果都是对应的十进制。
2、parseInt的第二个参数可以指定进制。
对象转换为数值
调用valueOf方法,如果结果为null,则调用toString方法,然后按照字符串的规则来。
转换为字符串
除了undefined和null,其它类型都有toString()方法。数值类型调用此方法时可以传入一个表示进制的参数。对于undefined和null,通过String函数来转换为字符串。
递增/递减
会将其它变量强制转换为数值类型,对于对象会调用其valueOf方法。
逻辑与/逻辑或
短路操作符:如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。
与:如果第一个操作数能被转换为false,则返回第一个操作数。
或:如果第一个操作数能被转换为true,则返回第一个操作数。
乘除法、取模的转换:
数值优先级最高。
Infinity * 0 = NaN
加减法的转换:
加法中字符串优先级最高,其次是数值;减法中,数值优先级最高。
如果有任一操作符为NaN,或者转换后为NaN,则计算结果为NaN。
如果有一个操作数是对象,加法时优先调用其toString()方法,减法时优先调用其valueOf()方法。(如果没有valueOf则调用toString转换为字符串,进而再转换为数值。)
Infinity + (-Infinity)= NaN
大于小于的转换:
如果操作数都是字符串,则会逐个比较字符串中对应字符的编码。
如果有数值,将另一个操作数转换为数值。
如果有对象,会调用其valueOf()方法和toString()方法。
如果出现NaN,则结果一定为false。
相等操作符的转换:
数值优先级最高,其它类型(除了null和undefined)都会被转化为数值;null == undefined;NaN与任何值都不相等,包括它本身;null和undefined不会进行类型转换。
如果操作符两端都是对象,则比较它们是不是同一个对象;如果只有一端是对象,则调用其valueOf()方法后再进行比较。
11、C++中class的继承和多态