错误之处,欢迎指正,持续更新中。
1. http
协议和https
协议的区别是什么?
-
https
需要申请证书,并且把证书部署到服务器上,进行相关的配置。 -
http
的信息是明文传输,https
是用SSL/TLS
加密传输协议。 -
http
使用80
端口,https
使用443
端口。 -
http
协议是无状态,无连接的。
- 无状态:数据包的发送、接受都是相互独立的。
- 无连接:通信双方都不能长久的维持对方信息。
2. https
协议中s
指的是什么?
s
指的是SSL/TLS
协议。
该协议的作用是:
- 加密信息传播,无法被窃听。
- 配备身份证书,防止被冒充。
3. 简单介绍http
状态码。
-
2**
表示成功,例如200
。 -
3**
大部分表示重定向,请求的URL
已移走,返回信息中应该包含一个URL
,为资源现在所处的位置。 其中304
表示未修改,也就是自从客户端上次请求后,请求的内容未曾修改过,此时服务端返回304
,不会返回响应内容,进而节省带宽和开销。 -
4**
表示客户端错误,例如404
未找到资源,403
请求被服务器拒绝。 -
5**
表示服务端错误。
4. 简要说明get
和post
请求的区别?
-
get
的数据在URL
上是可见的。 -
get
请求对长度有限制。 -
get
请求的数据可以收藏为书签,post
不可以。 -
post
请求后,按后退、刷新按钮数据会被重新提交,get
不会。 -
get
编码类型为application/x-www-form-url
,
post
编码类型为encodeapplication/x-www-form-urlencoded
或multipart/form-data
-
get
历史参数会被保存在浏览器中,post
不会。 -
get
只允许发ASCII
,post
没有限制。 -
get
安全性相对来说较差,因为发送的数据是URL
的一部分。
5. 跨域问题是如何出现的以及如何解决?
访问的URL
,协议、域名、端口号,有任意一个不同就算跨域。
js
文件、css
文件、图片文件都是被允许跨域请求的。
后端接口数据,其他域的cookie
,其他域的缓存是不允许跨域请求的。
解决跨域:
-
JSONP
利用script
标签的src
属性允许跨域的机制来进行JSONP
请求,浏览器会将script
标签src
属性请求得到的数据,当作js代码执行。
JSONP
在发送的时候,URL
上参数会带一个callback
:
<script>
function func(message) {
console.log(message);
}
</script>
<script src="http://www.test.com/jsonp?callback=func" type="text/javascript" charset="utf-8"></script>
服务端会将callback
与要返回的数据进行拼接,上述代码返回的结果是func({"name": "chris"})
,执行这段代码,调用函数func
,传入的参数就是请求得到的数据,就打印出了返回的数据。
iframe
html1页面
/*http://127.0.0.1:5500/html1*/
let iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = "http://127.0.0.1:5501/html2.html#chrisdean"; //向html2页面传递#chrisdean
document.body.appendChild(iframe);
window.addEventListener("hashchange", () => {
console.log(location.hash.substring(1));
//监听当前页面的hash变化
});
html2页面
/*http://127.0.0.1:5501/html2*/
if (location.hash === '#chrisdean') {
const age = 22;
try {
parent.location.hash = age;
} catch (e) {
//IE、Chrome下的安全机制无法修改parent.location.hash,所以要利用一个中间的代理iframe
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = 'http://127.0.0.1:5500/html3.html#' + age;
document.body.appendChild(ifrproxy);
}
}
html3页面
/*http://127.0.0.1:5500/html3*/
parent.parent.location.hash = self.location.hash.substring(1);
- 代理
浏览器是禁止跨域的,但是服务端不禁止,在本地运行npm run dev
命令时实际上是用node
运行了一个服务器,因此proxy
实际上是将请求发给本地的服务器,再由本地服务器转发给目标服务器,做了一层代理。 - 解决线上跨域
使用nginx
反向代理。
6. 在浏览器输入URL
后发生了什么?
- 检查缓存中有没有这个域名对应的解析过的
IP
地址。 -
DNS
解析URL
,获取IP
地址。 - 根据
IP
建立TCP
连接。 - 发送
http
请求。 - 服务器处理请求,返回响应结果。
- 解析
html
标签,构建DOM
树。 - 解析
CSS
样式,生成CSS
规则树。 - 合并
DOM
树和CSS
规则树,生成render
树。 - 布局
render
树,尺寸、位置。 - 绘制
render
树,颜色。 - 浏览器将信息传递给
GPU
,最终显示在屏幕上。
7. 如何解决页面编码和被请求的资源编码不一致?
ajax
请求时传递的参数,如果是get
请求方式,参数如果传递中文,在有些浏览器会乱码,不同的浏览器对参数编码的处理方式不同,所以对于get
请求的参数需要使用 encodeURIComponent
。
8. 浏览器缓存是如何实现的?
浏览器在第一次请求资源后,会获取到请求的结果以及缓存标识,接下来,浏览器会根据第一次请求返回的响应头来确定缓存处理的方式,分别是强缓存和协商缓存。
- 强缓存
不会向服务器发送请求,直接从缓存中读取资源。
强缓存可以通过设置两种HTTP Header
实现:Expires
和Cache-Control
。
- 当
Cache-Control: max-age=300
时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。
Cache-Control
可以在请求头或者响应头中设置,并且可以组合使用。
no-cache
:客户端缓存内容,是否使用缓存则需要经过协商缓存来验证决定。表示不使用Cache-Control
的缓存控制方式做前置验证,而是使用Etag
或者Last-Modified
字段来控制缓存。这个名字有一点歧义,并不是说浏览器不能缓存,只是浏览器在使用缓存数据时,需要先确认一下资源文件是否还跟服务器保持一致。
no-store
:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存。
max-age
:max-age=xxx
表示缓存内容将在xxx
秒后失效。
一般,我们会设置Cache-Control
的值为public, max-age=xxx
,表示在xxx
秒内再次访问该资源,均使用本地的缓存,不再向服务器发起请求。
- 协商缓存
强缓存依据某个时间或者某个时间段,所以并不会响应服务端资源文件的变化,一旦资源文件发生了变化,那么强缓存的文件并不会在时间范围之内更改,这样就造成了服务器和浏览器文件不一致的问题,那么此时我们就需要使用协商缓存。
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
协商缓存可以通过设置两种HTTP Header
:Last-Modified
或者ETag
实现。
-
Last-Modified
是该资源文件最后一次更改时间,服务器会在Response Headers
中返回,浏览器在下一次发送请求时,放到Request Header
里的If-Modified-Since
里,服务器在接收到后也会做比对,如果相同则命中协商缓存。 -
Etag
是服务器响应请求时,返回当前资源文件的一个唯一标识,只要资源有变化,Etag
就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag
值放到Request Header
里的If-None-Match
里,服务器只需要比较客户端传来的If-None-Match
跟自己服务器上该资源的ETag
是否一致,就能很好地判断资源相对客户端而言是否被修改过了。