浏览器缓存
优点
- 缓存可以帮助我们做性能优化,可以显著减少网络传输所带来的损耗
- 减少服务器负担,提升网站性能
- 减少不必要的数据传输,节省宽带
缺点
- 如果资源有更改但是客户端更新不及时,造成用户获取信息滞后
强缓存
强缓存就是向浏览器缓存查找该请求的结果,根据该结果的缓存规则决定是否使用该缓存
强缓存存在三种情况
- 不存在该请求的缓存结果和缓存标识,强缓存失效,直接向服务器发起请求
- 存在该请求的缓存和缓存标识,但是结果已经失效,强缓存失效,采用协商缓存,携带该缓存的标识向服务器发起请求
- 存在该请求的缓存结果和缓存标识,结果没有失效,强缓存生效直接返回该缓存结果
强缓存的缓存规则
服务器端在response.header对文件做缓存配置,缓存类型、缓存时间等
Expires设置缓存过期时间 (cache-control优先级比expires高)
? Expires设置缓存时间会存在客户端和服务器端时间存在误差的问题,强缓存会直接失效
respone header 的cache-control,常见的设置是
- max-age 缓存的时间
- public 客户端和服务器端都可以缓存
- private 只有客户端可以缓存
- no-cache 跳过设置强缓存
- no-store 客户端和服务器端都不缓存
协商缓存
当强缓存失效后,浏览器携带缓存标识想服务器发起请求,由服务器根据缓存标识决定是否使用缓存。
协商缓存存在两种情况
- 协商缓存生效,该请求的资源没有更新返回304
- 协商缓存失效,该请求的资源更新返回200和新的请求结果
协商缓存的标识也会在响应报文的http请求头和请求结果一起返回给浏览器,控制协商缓存的字段有
Last-Modified/If-Modified-Since和Etag / If-None-Match,其中Etag/If-None-Match优先级比其他几个高
Last-Modified / If-Modified-Since
- Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
- If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间,如果服务器资源修时间大于此值表示资源有更新,返回200和更新的资源,如果小于此值,表示资源没有更新返回304,继续使用浏览器中的缓存。
Etag / If-None-Match
- Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
- If-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。把此值与Etag作对比,一致返回304,资源没有更新,否则不一致返回200和更新的资源,资源更新
总结
强缓存优先于协商缓存,但是当强缓存失效则进行协商缓存,协商缓存是由服务器决定是否使用缓存,如果协商缓存也失效那么重新请求获取结果然后在存在浏览器中,协商缓存生效服务器返回304,继续使用缓存。
跨域的解决方法
-
jsonp 在html中通过相应的标签去请求资源(script、img等)但是只能实现get请求 -
iframe标签跨域 -
postMessage跨域 h5中新增的API a.html
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
b.html
window.addEventListener('message', function(e) {
alert('data from domain1 ---> ' + e.data);
var data = JSON.parse(e.data);
if (data) {
data.number = 16;
window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
}
}, false);
-
CORS跨域 在服务器设置 Access-Control-Allow-Origin 设置为*时表示该资源谁都可以使用 response.setHeader("Access-Control-Allow-Origin", "http://localhost:9106");
-
服务器反向代理 location /apis {
rewrite ^.+apis/?(.*)$ /$1 break;
include uwsgi_params;
proxy_pass http://localhost:1894;
}
-
websocket socket.io跨域 ? 前端 <div>user input:<input type="text"></div>
<script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script>
<script>
var socket = io('http://www.domain2.com:8080');
socket.on('connect', function() {
socket.on('message', function(msg) {
console.log('data from server: ---> ' + msg);
});
socket.on('disconnect', function() {
console.log('Server socket has closed.');
});
});
document.getElementsByTagName('input')[0].onblur = function() {
socket.send(this.value);
};
</script>
? nodejs 后台 var http = require('http');
var socket = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-type': 'text/html'
});
res.end();
});
server.listen('8080');
console.log('Server is running at port 8080...');
socket.listen(server).on('connection', function(client) {
client.on('message', function(msg) {
client.send('hello:' + msg);
console.log('data from client: ---> ' + msg);
});
client.on('disconnect', function() {
console.log('Client socket has closed.');
});
});
-
vue和react中跨域 vue在vue.config.js中的devServer中配置 devServer: {
proxy: {
'/wxapp': {
target: 'https://api.smzdm.com',
changeOrigin: true
},
'/home': {
target: 'https://api.smzdm.com/v1',
changeOrigin: true
},
'/v1':{
target: 'https://api.smzdm.com',
changeOrigin:true
}
}
react在webpack.config.js中的devServer中配置 devServer: {
contentBase: './dist',
port: 8080,
historyApiFallback: true,
proxy: {
'/api': {
target: 'http://localhost:9000',
pathRewrite: { '^/api': '' },
},
},
}
-
服务器中间件代理 var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();
app.use('/', proxy({
target: 'http://www.domain2.com:8080',
changeOrigin: true,
onProxyRes: function(proxyRes, req, res) {
res.header('Access-Control-Allow-Origin', 'http://www.domain1.com');
res.header('Access-Control-Allow-Credentials', 'true');
},
cookieDomainRewrite: 'www.domain1.com'
}));
app.listen(3000);
console.log('Proxy server is listen at port 3000...');
线程和进程 https://www.zhihu.com/question/25532384 ? 进程和线程都是一个时间段的描述,是CPU工作时间的描述。是运行中的程序指令的一种描述 ? 进程和线程都可以并发执行
-
线程 cpu调度的最小单位
- 线程在进程下进行
- 一个进程包含多个线程
- 同一进程下的不同线程间数据容易共享
- 一个线程挂掉会导致整个进程挂掉
-
进程 资源分配的最小单位
- 不同进程间数据很难共享
- 进程间不会相互影响
- 进程更加消耗计算机资源
堆、栈、队列
url从输入到渲染页面的过程
- 浏览器构建HTTP Request请求,DNS解析URL地址、生成Http请求报文、构建Tcp连接、使用IP协议选择传输路线
- 请求通过网络传输到服务器,(通过集线器、交换机、路由器等)
- 服务器构建HttpResponse响应,响应客户端的请求,将响应体的数据返回给客户端
- 浏览器开始页面渲染,解析HTML、CSS、JS生成RenderTree渲染页面
浏览器渲染页面解析过程
根据html文件构建DOM树和CSSOM树,构建DOM树期间,如果遇到JS会阻塞DOM树和CSSOM树的构建,优先加载JS,加载完JS后在继续构建DOM树和CSSOM树。如果JS操作了DOM根据操作的大小浏览器对页面进行重绘或重排。
- 解析html:按顺序解析,并在解析的过程中构建DOM树
- 构建dom树:和步骤1同步进行,一边解析一边构建
- 构建呈现renderTree 将dom树和css树结合
- 布局 计算renderTree节点的大小和位置,递归进行
- 绘制 布局完成后,将renderTree绘制在屏幕上
回流和重绘
回流reflow 当页面中的一部分因为尺寸、布局、隐藏等改变重新构建成为回流
重绘 当页面中的一部分元素需要更新属性,这个只会影响到外观、风格而不会影响到布局等操作就是重绘。
浏览器事件循环机制
js中的任务分为宏任务和微任务,都采用先进先出的执行策略,同步任务都在宏任务中。
宏任务主要有:script(整体代码)、setTimeout、setInterval、I/O、UI 交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境)。
微任务主要有:Promise.then、 MutationObserver、 process.nextTick(Node.js 环境)。
具体步骤:
- 从宏任务头部取出一个任务执行
- 执行过程中若遇到微任务则将其加到微任务队列中
- 宏任务执行完毕后,微任务队列中如果存在则挨个执行
- 微任务执行完后回到宏任务继续执行
Nodej中的eventloop
- timers 执行setTimeout和setInterval中到期的callback
- pending callback 上一轮中少数的callback会放在这一阶段执行
- idle,prepare 仅在内部使用
- poll 最重要的阶段,执行pending callback,在适当的情况下会阻塞在这个阶段
- check 执行setImmediate(setImmediate()是将事件插入到事件队列尾部,主线程和事件队列的函数执行完成后立即执行setImmediate指定的回调函数)的callback
- close callbacks 执行close事件的callback
post和get的区别
-
get在浏览器回退时是无害的,post会再次提交请求。 -
get请求还会被浏览器主动cache,post不会除非手动设置 -
get请求只能进行url编码,而post支持多种编码方式
- Content-Type:application/x-www-form-urlencoded 原生表单
- Content-Type:application/json 参数已json形式放到消息体中 编码utf-8
- Content-Type:text/xml 参数以string类型即可
- multipart/form-data 表单上传文件时,form表单的enctype属性
-
get请求的参数会保留在浏览器历史中,post不会 -
get请求url传参有长度限制,并且只接受ASCII字符,post没有限制 -
get参数暴露在url上 post放在request body中 -
get产生一个tcp数据包,pos它产生两个tcp数据包 ? 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); ? 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
移动端1px边框解决
-
使用border-image实现 div
{
-moz-border-image:url(/i/border.png) 30 30 stretch;
-webkit-border-image:url(border.png) 30 30 stretch;
-o-border-image:url(border.png) 30 30 stretch;
border-image:url(border.png) 30 30 stretch;
}
-
background-image .background-image-1px {
background: url(../img/line.png) repeat-x left bottom;
-webkit-background-size: 100% 1px; background-size: 100% 1px;
}
-
伪元素+transfrom ? 构建一个伪元素border为1px,在以transform缩放到50%
.border-1px {
position: relative;
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border-1px:before {
content: " ";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 1px;
border-top: 1px solid #D9D9D9;
color: #D9D9D9;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
原文链接:https://blog.csdn.net/yexudengzhidao/article/details/98480173
-
js计算rem基准值和viewport缩放值 ? 用JS根据屏幕尺寸和dpr精确地设置不同屏幕所应有的rem基准值和initial-scale缩放值
var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');
dpr = window.devicePixelRatio || 1;
rem = 100 * (docEl.clientWidth * dpr / 750);
scale = 1 / dpr;
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');
docEl.setAttribute('data-dpr', dpr);
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';
解决input在ios有阴影问题
input{
-webkit-appearance: none;
}
布局的几种方式
- 文档布局 普通流 从左到右,从上到下
- 浮动布局
- 定位布局
- 流式布局 用百分比做单位
- 弹性布局 flex em rem做单位
- 自适应布局 根据媒体查询
- 响应式布局 流式布局和自适应布局设计理念的融合。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。响应式几乎已经成为优秀页面布局的标准,每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变媒体查询+流式布局
Cookie
服务器端可以通过响应头中的set-Cookie设置cookie发送给客户端。
Cookie的有效期可以通过Expire和Max-Age设置
- Expire就是过期时间
- Max-Age用的是一段时间间隔,单位是秒,从浏览器接收到报文开始计算
作用域
关于cookie作用域有两个属性:Domain和path
Domain
domain表示cookie所在的域,默认为请求的地址,如网址为www.study.com/study,那么domain默认为www.study.com。而跨域访问,如域A为t1.study.com,域B为t2.study.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.study.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.study.com。注意:一般在域名前是需要加一个".“的,如"domain=.study.com”。
path
path表示cookie所在的目录,默认属性为 / ,就是根目录,表示该域名下的任何路径都可以使用cookie。
安全
如果带有Secure属性表示只能通过HTTPS传输cookie,
带有httpOnly属性表示只能通过HTTP协议传输,并且不能通过JS访问cookie,这一样可以预防XSS攻击。
对于CSRF攻击,可以使用SameSite属性,有三个值:
- Strict模式,浏览器禁止第三方请求携带Cookie,比如请求
sanyuan.com 网站只能在sanyuan.com 域名当中请求才能携带 Cookie,在其他网站请求都不能 - Lax模式 ,只能在get方法提交表单或者a标签发送get请求的情况下才可以携带Cookie,其他情况都不可以
- None模式, 这是默认模式,此模式下请求会自动携带Cookie
缺点
- 容量缺陷,cookie携带数据大小只有4kb
- 性能缺陷,cookie紧跟在域名后面,不管域名下的某一个地址是否需要cookie,请求都会携带完整的cookie。随着请求增多,会造成巨大性能浪费,请求携带大量不需要的内容。但是可以通过Domain和path指定作用域来解决。
- 安全缺陷, cookie是以纯文本的形式在浏览器和服务器中传递的,很容易被截取然后进行篡改,在cookie有效期内重新发送给服务器跟危险,而且在httpOnly为false的情况下Cookie能够被JS直接获取。
打开谷歌浏览器有四个进程
一个网络进程,一个浏览器进程,一个GPU进程,一个渲染进程
cookie和session的区别
- 存储位置 存储位置不同cookie存放在客户端浏览器,session存放在服务器上
- 容量不同 耽搁cookie保存数据最大4kb,一个站点最多保存20个cookie,而session没有上限,但是要考虑服务器的性能
- 存储方式 cookie只能保管ascii字符串,需要通过编码方式存储为unicode字符或二进制数据。session能储存任何类型的数据
- 有效期不同 cookie可以设置属性控制cookie的有效期,session过期时间默认为-1,关闭窗口就失效。
- 跨域 cookie支持跨域名访问,session不支持跨域名访问
UDP和TCP
TCP
TCP(传输控制协议)是面向连接的协议,在收发数据前必须和对方建立可靠的连接,一个tcp连接必须经过三次对话才能建立起来,经过三次“对话”才能正式发送数据。断开连接要进行四次。
优点
tcp提供可靠、稳定的服务,通过tcp连接传送的数据,无差错,不丢失,不重复,且按序到达。连接之前会有三次握手建立连接,数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完之后还会断开连接节约资源。通过校验,重传控制,序号标识,确认应答实现可靠传输,当丢包时的重发控制可以对次序乱掉的分包进行顺序控制。
缺点
传输慢、效率低、占用系统资源高,容易被攻击,在建立连接之前三次握手消耗时间,连接还会占用系统的cpu,内存等资源。确认机制和三次握手容易被人利用,实现DOS等攻击。TCP每条连接只能是点对点的。采用复杂的拥塞控制算法。
UDP
UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,使用UDP协议时不需要建立连接,只需要知道对方IP地址和端口号就可以直接发送数据包,但是能不能到达不知道。一台服务机可以同时向多个客户机传输相同消息。DHCP就是基于UDP协议,比如直播、实时游戏、物联网等
优点
传输速度快,比tcp安全,没有tcp的握手、确认等机制,UDP是无状态的传输协议,所以传输速度很快,工作效率比TCP高,适用于高速传输和实时性较高的通信或广播通信,而且被攻击的漏洞就少一点。UDP支持一对一,一对多,多对一和多对多的交互通信。
缺点
不可靠,不稳定,当网络质量不好时容易丢包
TCP和UDP的区别
- TCP面向连接,UDP是无连接的
- TCP保证数据的正确性,提供可靠的服务,数据无差错,不重复,不丢失,按序到达;UDP尽最大努力交付单数不保证可靠交付
- UDP有较好的实时性,工作效率比TCP高,使用与高速传输和实时性较高的通信或广播
- TCP对系统资源要求较多,UDP对系统资源要求较少
- TCP面向字节流,UDP是基于数据报
采用复杂的拥塞控制算法。
UDP
UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,使用UDP协议时不需要建立连接,只需要知道对方IP地址和端口号就可以直接发送数据包,但是能不能到达不知道。一台服务机可以同时向多个客户机传输相同消息。DHCP就是基于UDP协议,比如直播、实时游戏、物联网等
优点
传输速度快,比tcp安全,没有tcp的握手、确认等机制,UDP是无状态的传输协议,所以传输速度很快,工作效率比TCP高,适用于高速传输和实时性较高的通信或广播通信,而且被攻击的漏洞就少一点。UDP支持一对一,一对多,多对一和多对多的交互通信。
缺点
不可靠,不稳定,当网络质量不好时容易丢包
TCP和UDP的区别
- TCP面向连接,UDP是无连接的
- TCP保证数据的正确性,提供可靠的服务,数据无差错,不重复,不丢失,按序到达;UDP尽最大努力交付单数不保证可靠交付
- UDP有较好的实时性,工作效率比TCP高,使用与高速传输和实时性较高的通信或广播
- TCP对系统资源要求较多,UDP对系统资源要求较少
- TCP面向字节流,UDP是基于数据报
|