WEB标准不是某一个标准,而是一系列标准的集合。网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)。对应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript等。
标签闭合、标签小写、不乱嵌套、提高搜索机器人搜索机率、使用外链css和js脚本、结构行为表现的分离、文件下载与页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组件,容易维护、改版方便,不需要变动页面内容、提供打印版本而不需要复制内容、提高网站易用性。
为什么将css引入放头部,js引入放后面?
浏览器从上到下依次解析html文档。将css文件放到头部,css文件可以先加载。避免先加载body内容,导致页面一开始样式错乱,然后闪烁。
将javascript文件放到底部是因为:若将javascript文件放到head里面,就意味着必须等到所有的javascript代码都被下载、解析和执行完成之后才开始呈现页面内容。这样就会造成呈现页面时出现明显的延迟,窗口一片空白。
style 标签写在 body 后和 body 前有什么区别?
页面加载自上而下,当然是需要先加载样式。
写在body标签后,由于浏览器以逐行方式对HTML文档进行解析,当解析写在尾部的样式表会导致浏览器停止之前的渲染,等待加载且解析样式表后才重新进行渲染,这样可能导致留白现象(所以最好将style标签写在body前)。
‘流’是css的一种基本定位和布局机制,HTML默认的布局机制就是’流布局’,是一种自上而下(例如块级元素div),从左到右排列的布局方式。
两种类型 & 区别
IE盒模型(怪异盒模型):
width = border + padding + content
;
一个块的宽度 = width + margin
。
W3C盒模型(标准盒模型):
width = content
;
一个块的宽度 = width + padding + border + margin
。
切换方式
box-sizing: border-box; // IE盒模型标准
box-sizing: content-box; // W3C盒模型标准
margin | padding 分别适用于什么场合
margin:在border外侧需要留空
padding:在border内侧需要留空
HTML称为超文本标记语言,是一种标识性的语言。它包括一系列标签.通过这些标签可以将网络上的文档格式统一。HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字,图形、动画、声音、表格、链接等。
HTML存在两种文档类型
怪异模型(默认):浏览器按照自己的方式解析
标准模式:按照W3C标准
如何避免浏览器的怪异模式?
通过声明文档的解析类型
header,footer
等,让结构更加清晰,有利于浏览器的解析。可替换元素:其内容是通过标签类型以及其属性值来决定的。例如:iframe、video、img
。
非可替换元素:其内容由其标签包裹内容决定。例如div、p、span、ul、li、ol
。
行内元素:
span、a、img(行内替换元素)
块级元素:
h1~h6、p、div
header、footer、article、aside、caption、nav
等canvas
video
和音频audio
属性 | 描述 |
---|---|
name | 用于描述网站 |
http-equiv | 没有name时,可以采用这个属性的值(content-type,expires(期限),refresh,set-cookie,content属性关联到http请求头) |
content | 名称/值 中的值,可以是任意有效字符串 |
scheme | 用于指定要用来翻译属性值的方案 |
header、footer、article、aside、caption、nav
等。iframe 是一种内联框架,也是一种很常见的网页嵌入方式。
优点:
缺点:
Css引入方式有4种 内联、内嵌、外链、导入。
通过link和@import引入有什么区别?
id选择器、类选择器、标签选择器、相邻选择器(h1+p
)、子选择器(ul>li
)、后代选择器(li a
)、通配符选择器(*
)、属性选择器(a[rel = "XXX"]
)、伪类选择器、伪元素选择器、分组选择器
CSS3新增伪类
x:first-of-type
:选择属于其父元素的首个
元素的每个
元素
x:last-of-type
:选择属于其父元素的最后一个
元素的每个
元素
x:only-of-type
:选择属于其父元素唯一的
元素的每个
元素
x:only-child
:选择属于其父元素的唯一子元素的每个
元素
x:nth-child(1)
:选择属于其父元素的第一个子元素的每个
元素
等等
Css伪类与伪元素的区别
伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性。
与伪类针对特殊状态的元素不同的是,伪元素对元素中的特定内容进行操作。但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素。
用户操作伪类
推荐书写样式顺序:link、visited、focus、hover、active
:first-line、:first-letter、:before、:after、:enabled、:disabled、:checked
:enabled
:每个已启用的元素(多用于表单元素 例如input):disabled
:控制表单控件的禁用状态:checked
:单选框或复选框被选中:before
:在元素之前添加内容(可用来做清除浮动):after
:在元素之后添加内容font-size, font-family, color...
border, padding, margin, width, height...
css选择器的解析是从右向左解析,为了避免对所有元素进行解析
各种css选择器
1)E:last-child
匹配父元素的最后一个子元素E。
2)E:nth-child(n)
匹配父元素的第n个子元素E。
3)E:nth-last-child(n)
CSS3 匹配父元素的倒数第n个子元素E。
圆角border-radius
多列布局 详情
文本效果
@Font-face
特性
线性渐变
linear-gradient(left, red, blue)
transform 样式
translate()
:元素从其当前位置移动,根据给定的 left(x 坐标) 和 top(y 坐标) 位置参数
rotate()
:元素顺时针旋转给定的角度。
scale()
:元素的尺寸会增加或减少。
skew()
:元素翻转给定的角度,根据给定的水平线(X 轴)和垂直线(Y 轴)参数
matrix()
:把所有 2D 转换方法组合在一起
过渡 transition: property duration timing-function delay;
property
:规定设置过渡效果的 CSS 属性的名称。
duration
:规定完成过渡效果需要多少秒或毫秒。
timing-function
:规定速度效果的速度曲线。
delay
:定义过渡效果何时开始。
动画 animation
flex布局 详情:见文本的‘布局–flex布局’
媒体查询 联系文本的“布局–响应式布局–原理”
@media screen and (max-width: 300px) {
body {background-color:lightblue;}
}
不同浏览器的标签默认的padding/margin不同,通过初始化css样式可以解决。
*{
margin:0;
padding:0px;
}
IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()
获取自定义属性。
Chrome中文界面下默认会将小于12px的文本强制为12px。
通过加入css属性 -webkit-text-size-adjust:none;
可以解决,或者使用transform
中的scale()
缩放属性
超链接访问过后hover样式就不出现,因为被点击访问过的超链接样式不再具有hover
和active
了。
解决方法是改变css属性的排列顺序:
a:link{} → a:visited{} → a:focus → a:hover{} → a:active{}
display:none
隐藏对应的元素,在文档布局中不再分配空间(导致重排)
visibility:hidden
隐藏对应的元素,在文档布局中保留原来的空间(导致重绘)
relative
:相对定位,相对于自身位置进行定位absolute
:绝对定位,相对于position不为static的第一个父级元素进行定位fixed
:固定定位。相对于浏览器窗口进行定位inherit
:继承父级元素position属性值static
:默认值,即没有定位,仍为文档流sticky
:粘性定位详情position:sticky
同时给一个(top,bottom,right,left)之一即可overflow:hidden
或者overflow:auto
属性。scroll
:必定出现滚动条auto
:子元素内容大于父元素时出现滚动条visible
:溢出的内容出现在父元素之外hidden
:溢出时隐藏CSS控制文字,超出部分显示省略号
设置属性 background-position:center;
{
width:0px;
height:0px;
border-top:10px solid transparent;
border-left:10px solid transparent;
border-right:10px solid transparent;
border-bottom:10px solid #000;
}
触发BFC方式 4个
BFC的布局规则 6个
BFC的作用
text-align:center
margin:0 auto
margin-left:负宽度/2
(前提父元素设置相对定位){
width:100px;
position:absolute;
left:50%;
margin-left:-50px
}
display:table; margin: 0 auto;
display:inline-block; text-align:center;
绝对定位 + transform
{
position: absolute;
left: 50%;
transform: translateX(-50%);
}
万能flex布局(个人推荐)
{
display:flex;
justify-content:center;
}
line-height: 盒子高度;
适合纯文字类内容居中
父元素设置相对定位,子元素设置绝对定位,标签通过margin实现自适应居中
万能flex
{
display:flex;
align-items:center;
}
父元素设置相对定位,子元素设置绝对定位,通过transform实现居中。
父元素设置display:table
+ 子元素设置vertical-align:middle
。
flex
{
display:flex;
justify-content:center;
align-items:center;
}
position + transform (宽高未知)
.parent{
position:relative;
}
.child{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
position + margin (宽高确定)
.parent{
position: relative;
}
.child{
width: 100px;
height: 100px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: -50px;
}
绝对定位设置各个方向为0,通过margin:auto
实现垂直水平居中(宽高已知)
.parent{
position: relative;
}
.child{
width: 100px;
height: 100px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
当元素设置了浮动后,可以向左向右移动,直到它的外边缘碰到包含它的框或者另外一个浮动元素的边框为止。
浮动元素脱离了正常文档流,可以想象成浮动元素浮在了正常文档流上方,文档流不再有这个元素存在。
优点
在图文混排的场景下十分适用,可以实现文字环绕图片的效果,当元素浮动后,它有着块级元素的特点(可设置宽高),但它与inline-block存在差别。
float可以在横向排序上设置方向,而inline-block不可。
inline-block会出现存在空白间隙情况。
缺点
float致使元素脱离文档流,若父元素高度自适应,则会引起父元素高度塌陷。
额外标签法(不推荐):在最后一个浮动标签后,新加一个标签,给其设置clear:both;
。
父级添加overflow属性(不推荐):
父元素添加overflow:hidden。
原理:触发BFC。(联系:文本的‘BFC–BFC的作用’)
使用after伪元素清除浮动(推荐使用)
.clearfix:after{
//伪元素是行内元素 正常浏览器清除浮动方法
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.clearfix{
*zoom: 1;
//ie6清除浮动的方式,前面加*是hack写法,*号只有IE6-IE7执行,其他浏览器不执行
//ie6-7不支持伪元素:after,使用zoom:1触发hasLayout.
}
使用before和after双伪元素清除浮动
.clearfix:after,.clearfix:before{
content: "";
display: table;
}
.clearfix:after{
clear: both;
}
.clearfix{
*zoom: 1;
}
设置元素浮动后,display会变成block
详情
该布局提供了一种更高效的方法对容器中的项目进行布局、对齐和分配空间,他没有方向上的限制,可以由开发人员自由操作。
flex-direction: row | row-reverse | column | column-reverse;
:决定主轴方向(容器排列方向)flex-wrap: nowrap | wrap | wrap-reverse;
:如果一条轴线排不下,定义换行规则flex-flow: || ;
:flex-direction和flex-wrap的简写形式justify-content: flex-start | flex-end | center | space-between | space-around;
:定义容器在主轴上的对齐方式。align-items: flex-start | flex-end | center | baseline | stretch;
:定义容器在交叉轴上的对齐方式。align-content: flex-start | flex-end | center | space-between | space-around | stretch;
:定义多根轴线的对齐方式,如果容器只有一根轴线,该属性不起作用。order
:定义项目的排列顺序,数值越小,排列越靠前,默认为0。
flex-grow
:定义项目的放大比例,默认为0(即如果存在剩余空间,也不放大)。
flex-shrink
:定义项目的缩小比例,默认为1(即如果空间不足,该项目将缩小)。
flex-basis
:定义了在分配多余空间之前,项目占据的主轴空间。默认值为auto(项目本来大小)。
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
:
是flex-grow
、flex-shrink
和flex-basis
的简写,默认值为 0 1 auto
。
该属性有两个快捷值: auto(1 1 auto)
和 none(0 0 auto)
。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
align-self: auto | flex-start | flex-end | center | baseline | stretch;
:
允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性,默认值为auto(表示继承父元素align-items属性,如果没有父元素,等同于stretch)
是指网站能够兼容多个终端,而不是为每一个终端特地去开发新的一个版本。
左右容器固定,中间容器自适应
<div class="container">
<div class="left">leftdiv>
<div class="main">maindiv>
<div class="right">rightdiv>
div>
flex
.container{
display: flex;
}
.left{
flex-basis:200px;
background: green;
}
.main{
flex: 1;
background: red;
}
.right{
flex-basis:200px;
background: green;
}
position + margin
.left,.right{
position: absolute;
top: 0;
background: red;
}
.left{
left: 0;
width: 200px;
}
.right{
right: 0;
width: 200px;
}
.main{
margin: 0 200px ;
background: green;
}
float + margin
.left{
float:left;
width:200px;
background:red;
}
.main{
margin:0 200px;
background: green;
}
.right{
float:right;
width:200px;
background:red;
}
方法一 flex
<html>
<head>
<meta charset="utf-8" />
<title>自适应填补 方法一 flextitle>
<style>
*{
margin: 0;
padding: 0;
font-size: 0;
}
.father{
display: flex;
flex-direction: column;
width: 500px;
height: 700px;
background: blue;
}
.child1{
flex-basis: 100px;
background: blueviolet;
}
.child2{
flex: 1;
background: brown;
}
style>
head>
<body>
<div class="father">
<div class="child1">div>
<div class="child2">div>
div>
body>
html>
方法二 定位
<html>
<head>
<meta charset="utf-8" />
<title>自适应填补 方法二 定位title>
<style>
*{
margin: 0;
padding: 0;
font-size: 0;
}
.father{
position: relative;
width: 500px;
height: 700px;
background: blue;
}
.child1{
height: 100px;
background: blueviolet;
}
.child2{
position: absolute;
top: 100px;
bottom: 0;
width: 100%;
background: brown;
}
style>
head>
<body>
<div class="father">
<div class="child1">div>
<div class="child2">div>
div>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轮播图实现title>
<style type="text/css">
.wrapper-container {
position: relative;
width: 500px;
height: 400px;
overflow: hidden;
margin: 0 auto;
}
.wrapper {
position: absolute;
left: 0;
top: 0;
width: 300%;
transition: all ease .5s;
}
.wrapper img {
width: 500px;
/* display: block; */
float: left;
}
style>
head>
<body>
<div class="wrapper-container">
<div class="wrapper" id="wrapper">
<img src="./images/1.jpg" alt="">
<img src="./images/2.jpg" alt="">
<img src="./images/3.jpg" alt="">
div>
div>
body>
<script type="text/javascript">
let index = 0,
dom = document.querySelector("#wrapper"),
timer = null,
childLength = dom.children.length,
stepWidth = dom.children[0].offsetWidth
timer = setTimeout(autoPlay, 3000)
function autoPlay () {
index++
index = index === childLength ? 0 : index
dom.style.left = -index * stepWidth + 'px'
timer = setTimeout(autoPlay, 3000)
}
script>
html>
原理类似于轮播图,整体元素一直排列下去,假设有5个需要展示的全屏页面,那么高度将会是500%,但我们只能展示100%,剩下的内容可以通过transform进行Y轴定位,也可以通过margin-top实现。
<html>
<head>
<meta charset="utf-8" />
<title>全屏滚动title>
<style type="text/css">
* {
margin: 0;
padding: 0;
font-size: 0;
}
.box {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
ul {
position: relative;
}
li {
width: 100%;
height: 100vh;
font-size: 30px;
position: relative;
display: flex;
justify-content: center;
text-align: center;
}
li p {
font-size: 30px;
position: absolute;
bottom: 0;
}
style>
head>
<body>
<div class="box">
<ul style="top: 0;">
<li style="background-color: yellowgreen;">一页面<p>一页面p>
li>
<li style="background-color: red;">二页面<p>二页面p>
li>
<li style="background-color: skyblue;">三页面<p>三页面p>
li>
<li style="background-color: yellow;">四页面<p>四页面p>
li>
ul>
div>
<script type="text/javascript">
var kai = true,i=0;
var oUl = document.getElementsByTagName("ul")[0];
document.addEventListener('mousewheel', function(ev) {
var ev = window.event || ev;
if (kai) {
kai = false;
oUl.style.transition=" 0.5s ease"; // 原因见下
if (ev.wheelDelta < 0 && i<3) { //当滑轮向下滚动时
i++;
}
if (ev.wheelDelta > 0 && i>0) { //当滑轮向上滚动时
i--;
}
setTimeout(function() {
oUl.style.top = -i*100 + 'vh';
}, 0);
setTimeout(function() {
kai = true;
}, 1000);
}
});
// 因为高度为100vh 当窗口或框架被调整大小时, 100vh计算后的值变化, 就会有个缓慢变化的过程
// 即使改为 ul{ transition : top 0.5s ease;} 也不行
window.onresize=function(){
oUl.style.transition="none";
}
script>
body>
html>
代码摘自
搜索引擎后台是一个庞大的数据库,里面存储了大量的关键词,每个关键词对应着多个网页。这些网页由“搜索引擎蜘蛛”或“网络爬虫”在网络上收集的。“蜘蛛”每天在互联网上爬行,对网页的内容进行分析提炼,查找其中的关键词。如果“蜘蛛”认为关键词在数据库中没有且对用户是有用的便存入后台的数据库中,反之,如果“蜘蛛”认为是垃圾信息或重复信息,就舍弃不要。
一个关键字对应多个网址,与关键词最吻合的网址就会排在前面。如果网站内容可以被搜索引擎能识别,那么搜索引擎就会提高该网站的权重,增加对该网站的友好度。这样一个过程我们称之为SEO。
提高网站的权重,增强搜索引擎友好度,以达到提高排名,增加流量,改善(潜在)用户体验,促进销售的作用。
白帽SEO,起到了改良和规范网站设计的作用,使网站对搜索引擎和用户更加友好,并且网站也能从搜索引擎中获取合理的流量,这是搜索引擎鼓励和支持的。
网站结构布局优化
尽量简单、开门见山,提倡扁平化结构。
标签必须添加“alt”和“title”属性,告诉搜索引擎导航的定位,做到即使图片未能正常显示时,用户也能看到提示文字。网页代码优化
突出重要内容—合理的设计title、description和keywords
标题:只强调重点即可,尽量把重要的关键词放在前面,关键词 不要重复出现,尽量做到每个页面的
标题中不要设置相同的内容。
标签:关键词,列举出几个页面的重要关键字即可,切记过分堆砌。
标签:网页描述,需要高度概括网页内容,切记不能太长,过分堆砌关键词,每个页面也要有所不同。
语义化书写HTML代码,符合W3C标准
尽量让代码语义化,在适当的位置使用适当的标签,用正确的标签做正确的事。让阅读源码者和“蜘蛛”都一目了然。比如:h1-h6
是用于标题类的,标签是用来设置页面主导航,列表形式的代码使用
ul
或ol
,重要的文字使用strong
等。
标签
页内链接,要加 “title” 属性加以说明,让访客和 “蜘蛛” 知道。而外部链接,链接到其他网站的,则需要加上 rel="nofollow"
属性, 告诉 “蜘蛛” 不要爬,因为一旦“蜘蛛”爬了外部链接之后,就不会再回来了。
正文标题要用标签
h1标签自带权重“蜘蛛” 认为它最重要,一个页面有且最多只能有一个H1标签,放在该页面最重要的标题上面,如首页的logo上可以加H1标签。副标题用标签, 而其它地方不应该随便乱用 h 标题标签。
应使用 “alt” 属性加以说明
<img src="cat.jpg" width="300" height="200" alt="猫" />
当网络速度很慢,或者图片地址失效的时候,就可以体现出alt属性的作用,他可以让用户在图片没有显示的时候知道这个图片的作用。同时为图片设置高度和宽度,可提高页面的加载速度。
表格应该使用
表格标题标签
caption 元素定义表格标题。caption 标签必须紧随 table 标签之后,您只能对每个表格定义一个caption 标签。
<table border='1'>
<caption>表格标题caption>
<tbody>
<tr>
<td>appletd>
<td>100td>
tr>
<tr>
<td>bananatd>
<td>200td>
tr>
tbody>
table>
标签:只用于文本内容的换行
、
标签
需要强调时使用。标签在搜索引擎中能够得到高度的重视,它能突出关键词,表现重要的内容,
标签强调效果仅次于
标签;
、
标签:只是用于显示效果时使用,在SEO中不会起任何效果。
文本缩进 & 版权符号
文本缩进不要使用特殊符号
应当使用CSS进行设置。版权符号不要使用特殊符号 ©
可以直接使用输入法打出版权符号©。
重要内容不要用JS输出,因为“蜘蛛”不会读取JS里的内容,所以重要内容必须放在HTML里。
尽量少使用iframe框架,因为“蜘蛛”一般不会读取其中的内容。
谨慎使用 display:none;
对于不想显示的文字内容,应当设置z-index或缩进设置成足够大的负数偏离出浏览器之外。因为搜索引擎会过滤掉display:none
其中的内容。
前端网站性能优化
减少http请求数量
控制资源文件加载优先级
浏览器在加载HTML内容时,是将HTML内容从上至下依次解析,解析到link或者script标签就会加载href或者src对应链接内容,为了第一时间展示页面给用户,就需要将CSS提前加载,不要受 JS 加载影响。
一般情况下都是CSS在头部,JS在底部。
尽量外链CSS和JS(结构、表现和行为的分离),保证网页代码的洁,也有利于日后维护
<link rel="stylesheet" href="asstes/css/style.css" />
<script src="assets/js/main.js">script>
利用浏览器缓存
浏览器缓存是将网络资源存储在本地,等待下次请求该资源时,如果资源已经存在就不需要到服务器重新请求该资源,直接在本地读取该资源。
减少重排(Reflow)
基本原理:重排是DOM的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的visibility属性,这也是Reflow低效的原因。如果Reflow的过于频繁,CPU使用率就会急剧上升。
减少Reflow,如果需要在DOM操作时添加样式,尽量使用 增加class属性,而不是通过style操作样式。
减少 DOM 操作
图标使用IconFont替换
不使用CSS表达式,会影响效率
使用CDN网络缓存,加快用户访问速度,减轻服务器压力
启用GZIP压缩,浏览速度变快,搜索引擎的蜘蛛抓取信息量也会增大
伪静态设置
如果是动态网页,可以开启伪静态功能,让蜘蛛“误以为”这是静态网页,因为静态网页比较合蜘蛛的胃口,如果url中带有关键词效果更好。
动态地址:http://www.xxx.cn/index.php
伪静态地址:http://www.xxx.cn/index.html
解析HTML,生成DOM树,解析CSS,生成CSSOM树,解析HTML和解析CSS同时进行。
将DOM树和CSSOM树,关联起来,构建一棵渲染树(Render Tree)(这一过程又称为Attachment)。每个DOM节点都有attach方法,接受样式信息,返回一个render对象(又名renderer)。这些render对象最终会被构建成一棵渲染树(Render Tree)。
Layout(布局):根据生成的渲染树,进行布局(Layout),为每个Render树上的节点确定几何信息(位置,大小)。
Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
Display:将像素发送给GPU(图形处理器),展示在页面上。
详情
DNS缓存
DNS缓存是指在正常访问ip之后,系统会将这个ip存储起来,当再次访问的时候,系统就会把本地的DNS缓存提取显示,等于是加速了网址的解析。
DNS记录存储在区域文件中,用于将域名转换为IP地址,还包括域名的服务器名称和邮件服务器信息,由于DNS记录完全由文本组成,因此在需要时可以进行修改
CDN缓存
用户浏览器与服务器交互,没有接入CDN时:用户在浏览网站的时候,浏览器能够在本地保存网站中的图片或者其他文件的副本,这样用户再次访问该网站的时候,浏览器就不用再下载全部的文件,减少了下载量意味着提高了页面加载的速度。
接入CDN时:客户端浏览器先检查是否有本地缓存是否过期,如果过期,则向CDN边缘节点发起请求,CDN边缘节点会检测用户请求数据的缓存是否过期,如果没有过期,则直接响应用户请求,此时一个完成http请求结束;如果数据已经过期,那么CDN还需要向源站发出回源请求(back to the source request),来拉取最新的数据。
浏览器缓存
客户端缓存减少了服务器请求,避免了文件重复加载,显著地提升了用户体验。但是当网站发生更新时(如替换了css,js以及图片文件),浏览器本地仍保存着旧版本的文件,从而导致无法预料的后果。
服务器缓存
缓存指的是将需要频繁访问的网络内容存放在离用户较近、访问速度更快的系统中,以提高内容访问速度的一种技术。服务器缓存就是存放频繁访问内容的服务器。
物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
TCP 和 UDP 的区别
TCP 是面向连接的,UDP 是面向无连接的
TCP 结构复杂,包头长度较长;UDP程序结构较简单,UDP的包头长度为端口号长度(16)。
TCP 是面向字节流的,UDP 是基于数据报的
TCP 保证数据正确性,UDP 可能丢包
TCP 保证数据顺序,UDP 不保证
面向连接 & 面向无连接
在互通之前,面向连接的协议会先建立连接,如 TCP 有三次握手,而 UDP 不会。
三次握手
简单理解:
A:您好,我是 A
B:您好 A,我是 B
A:您好 B
为什么是三次握手?
总结的话就是通信双方全都有来有回。对于 A 来说它发出请求,并收到了 B 的响应,对于 B 来说它响应了 A 的请求,并且也接收到了响应。
TCP 的三次握手除了建立连接外,主要还是为了沟通 TCP 包的序号问题。
A 告诉 B,我发起的包的序号是从哪个号开始的,B 同样也告诉 A,B 发起的 包的序号是从哪个号开始的。
双方建立连接之后需要共同维护一个状态机,在建立连接的过程中,双方的状态变化时序图。
如图,刚开始的时候,客户端和服务器都处于 CLOSED 状态,先是服务端主动监听某个端口,处于 LISTEN 状态。然后客户端主动发起连接 SYN,之后处于 SYN-SENT 状态。服务端接收了发起的连接,返回 SYN,并且 ACK ( 确认 ) 客户端的 SYN,之后处于 SYN-SENT 状态。客户端接收到服务端发送的 SYN 和 ACK 之后,发送 ACK 的 ACK,之后就处于 ESTAVLISHED 状态,因为它一发一收成功了。服务端收到 ACK 的 ACK 之后,也处于 ESTABLISHED 状态,因为它也一发一收了。
四次挥手
简单理解如下:
A:B 啊,我不想玩了
B:哦,你不想玩了啊,我知道了
这个时候,只是 A 不想玩了,即不再发送数据,但是 B 可能还有未发送完的数据,所以需要等待 B 也主动关闭。
B:A 啊,好吧,我也不玩了,拜拜
A:好的,拜拜
这样整个连接就关闭了,当然上面只是正常的状态,也有些非正常的状态(比如 A 说完不玩了,直接跑路,B 发起的结束得不到 A 的回答,不知道该怎么办或则 B 直接跑路 A 不知道该怎么办),TCP 协议专门设计了几个状态来处理这些非正常状态。
断开的时候,当 A 说不玩了,就进入 FIN_WAIT_1 的状态,B 收到 A 不玩了的消息后,进入 CLOSE_WAIT 的状态。
A 收到 B 说知道了,就进入 FIN_WAIT_2 的状态,如果 B 直接跑路,则 A 永远处与这个状态。TCP 协议里面并没有对这个状态的处理,但 Linux 有,可以调整 tcp_fin_timeout 这个参数,设置一个超时时间。
如果 B 没有跑路,A 接收到 B 的不玩了请求之后,从 FIN_WAIT_2 状态结束,按说 A 可以跑路了,但是如果 B 没有接收到 A 跑路的 ACK 呢,就再也接收不到了,所以这时候 A 需要等待一段时间,因为如果 B 没接收到 A 的 ACK 的话会重新发送给 A,所以 A 的等待时间需要足够长。
TCP 为什么是可靠连接
详情
HTTP
超文本传输协议。
客户端和服务器端传递的是明文的消息。
采用80端口。
HTTPS
客户端(浏览器)向服务器请求https连接。
服务器发送了一个SSL证书给客户端,SSL证书中包含了具体的内容有证书的颁发机构、有效期、公钥、证书持有者、签名,通过第三方的校验保证身份的合法。
客户端会读取证书所有者、有效期等信息进行校验。
客户端(浏览器)开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发过来的证书的颁发CA比对,用于验证证书是否为合法机构颁发。
如果找不到,浏览器就会报错。
如果找到了,就会取出其中的公钥,对证书内的签名进行解密。
使用相同的Hash算法对签名进行去摘要并与服务器发来的摘要进行对比。如果对比一致,则合法,这样就得到公钥了
客户端随机的秘钥A(用于对称加密)。
客户端用公钥对A进行加密。
客户端将加密A后的密文发送给服务器。
服务器通过私钥对密文进行解密得到对称加密的秘钥。
客户端与服务器通过对称秘钥加密的密文通信。
【参考文档】: