假设输入 www.baidu.com
客户端与服务端进行数据交互的时候,不能识别域名,通过DNS解析域名转化未对用的IP地址
.com
就由负责.com
的顶级域名服务器管理,然后返回这个服务器的ip。顶级域名服务器(gTLD Server): .com、.cn等域名引出一个问题:为什么是三次?两次建立连接存在什么问题?四次呢
SYN=1
(SYN代表发起一个新连接),和一个随机的起始信号seq=x
(seq信号,32位,用于标识TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记)SYN=1
、ACK=1
(确认信号是有效的) 、ack=x+1
(ack序号,32位,只有在ACK标志位置1时,ack才是有效的,ack=seq+1)、随机产生一个的一个seq=y
ACK=1
、seq=x+1
、 ack=y+1
几种状态的说明:
解析html结构,构建dom树,那所有的标签解析出来
构建cssom树,解析css样式
执行script标签中的代码(所以避免将该标签放在头部,造成页面空白,形成阻塞 )
script
标签之后,加载脚本内容,然后执行,执行完毕之后继续解析htmlscript
之后,不发生阻塞,一边解析html,一遍加载脚本,等带html解析全部解析完成之后,在执行脚本将dom和cssom合并成渲染树
根据渲染树将页面绘制出来
引出一个问题:三次挥手行不行
FIN=1
(释放一个连接),seq=u
ACK=1
、ack=u+1
、seq=v
此时, 从客户机到服务器这个方向的连接就释放了, TCP连接处于半关闭状态. 但服务器若发送数据, 客户机仍要接收, 即从服务器到客户机的连接仍未关闭.FIN=1
、ACK=1
、seq=w
、ack=u+1
几种状态得说明:
FIN_WAIT_1客户端发送FIN=1得关闭连接得的请求之后进入该状态
CLOSE_WAIT :服务端收到客户端发送得关闭连接的请求后,确认信号是有效的,回应客户端之后进入
FIN_WAIT_2:客户端收到服务端响应的ACK之后进入。进入半关闭的状态,只能客户端只能接受数据,不能发送数据
LAST_ACK:服务端发送一个FIN关闭信号给客户端,等待对方确认
TIME_WAIT:客户端接收到服务端发送的FIN关闭信号之后进入,等待足够的时间2MSL,以此确保客户端收到确认关闭连接的ACK
CLOSED:连接结束
UDP | TCP | |
---|---|---|
是否连接 | 无连接,不用关心对方是否接收到 | 面向连接,需要确保双方建立正确的连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等),速度要求快 | 适用于要求可靠传输的应用,例如文件传输 |
无状态的,以请求/应答方式运行的协议,她使用可拓展的语义和自描述消息格式,与基于网络的超文本信息系统(html页面)灵活的互动
get:参数挂载在url上,只被用于获取数据
post:将实体提交到指定的资源,侧重于新增数据
put:侧重于修改数据 ,整体更新
patch:对put方法的额外补充,用于局部更新
delete:删除指定资源
head:与get相同,但是只返回响应头,没有响应主体
options:预检请求,检查服务器支持哪些http方法,响应体中包含一个Allow
字段,包含了所支持的方法
connect:创建一个客户端与请求资源之间双向通信的隧道,点对点通信
trace:服务端原样返回接收到的信息,提供了一种用于debug方法
RESTful是面向资源请求,url中不能存在动词,只能有名词。
https://api.example.com/v1/zoos
对于具体资源的操作,HTTP提供了上面的请求类型,可以使用这些动词来表对资源进行哪些操作,对于一些参数,比如:获取Tom的数学成绩,用get请求来写的话,请求地址就是/tom?subject=math
,但是用RESTful风格来写就是/tom/math
,列出一些常用例子:
//方法 接口 行为
GET /zoos: 列出所有动物园
POST /zoos: 新建一个动物园
GET /zoos/ID: 获取某个指定动物园的信息
PUT /zoos/ID: 更新某个指定动物园的信息(提供该动物园的全部信息)
PATCH /zoos/ID: 更新某个指定动物园的信息(提供该动物园的部分信息)
DELETE /zoos/ID: 删除某个动物园
GET /zoos/ID/animals: 列出某个指定动物园的所有动物
DELETE /zoos/ID/animals/ID: 删除某个指定动物园的指定动物
axios里面同样提供了这些请求方法的别名
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
Accept 浏览器可接受的数据格式
Accept-Encoding 浏览器可接收的压缩算法,如 gzip
Accept-lanuage 浏览器能接收的语言
Connection: keep-alive 一次TCP连接重复使用(一次连接,多次使用)
cookie 非跨域请求都会带上
Host请求的域名
User-Agent(简称 UA)发出请求的客户端,浏览器信息
Content-type 发送方数据的格式,如application/json
img
、link
、script
标签不受同源策略的影响。jsonp本质是动态创建script
标签,利用他不产生跨域的特点,向后台发送请求
script
标签,后台接收到请求之后,通过一些处理返回一个函数名,并且把数据当作参数放进去,返回sayName(‘Tom‘)
sayName
script
加载资源发送的请求是get请求,以至于jsonp也有这个局限。
同源策略仅仅是浏览器的限制,对于服务器之间的相互请求则不做限制
例如这里,前端需要向localhost:5000
请求数据。项目npm run dev
运行的时候,在本地启动了一个服务4000,前端发送请求的时候会经由4000,然后他再向5000发送请求,4000向5000转发请求不涉及跨域,请求成功之后,5000给4000返回响应,然后4000再转发给前端
proxyTable
(根据脚手架版本),这里就是利用了中间件,本地启动一个服务,所有的请求都发送到本地创建的服务,然后由他转发给后台跨域资源共享,关键实现在于服务端。
Access-COntrol-Allow-Origin
:关键属性,要么是请求时Origin
字段的值,要么是一个*
,表示接受任意域名的请求。Access-Control-Allow-Credentials
:默认为false
,表明请求是否携带credentials(代表cookies, authorization headers 或 TLS client certificates),Credentials必须在前后端都被配置(即后台Access-Control-Allow-Credentials
和 前端XHR 或Fetch request中都要配置)才能使带credentials的CORS请求成功。如果决定要发送cookie,那么Access-Control-Allow-Origin
属性不能设置成*
,必须指定必须的,于请求一致的域名origin
Access-Control-Expose-Headers
:出现在响应头中,暴露出来的响应头,供XMLHttpRequest对象的getResponseHeader()获取额外的头部信息Access-Control-Allow-Methods
:出现在预检请求的响应中,表明服务端支持跨域的方法Access-Control-Allow-Headers
:出现在预检请求的响应中,表示服务端支持的所有头部信息,如果请求头设置了Access-Control-request-Header
,那么该字段必需。Access-Control-Max-Age
:出现在预检请求的响应头中,表示预检请求的有效期,单位秒,在这个时间内不在发送预检请求Access-Control-Request-Method
:必选,出现在预检请求的请求头中,表示真正请求实会采用那种请求方法Access-Control-Request-Header
:出现在预检请求的请求头中,表示服务器在真正的请求中会采用哪些请求头配置nginx的nginx.conf
文件
浏览器访问 http://localhost:81
时,转发到 https://mywebsite.com
server {
#访问的端口号
listen 81;
#访问的地址
server_name localhost;
location / {
root html;
index index.html index.htm;
#转发的地址
proxy_pass https://mywebsite.com;
}
}
向服务器请求数据时,会又优先查询浏览器缓存,如果缓存中存在需要请求的数据,就直接从浏览器缓存中提取出来数据,常见的http缓存只能缓存get请求响应的资源
http缓存分类:根据是否重新向服务器发起请求来分类,可分为强缓存和协商缓存
http缓存过程:
强制缓存在缓存未过期的情况下,即Cache-Control的max-age属性
或者Expires
未过期,那么就会去返回浏览器的缓存,强制缓存生效时,http状态码是200,这种方式是页面加载速度最快的,因为他没有与服务器进行交互。但是假如在服务器的资源被修改了,这时候拿到的缓存就不是我们预期的数据了,页面上刷新了但没有生效,因为走的是强制缓存,所以Ctrl + F5一顿操作之后就好了。 跟强制缓存相关的header头属性有(Pragma/Cache-Control/Expires)
相关属性:
Cache-Control
:
no-store
:禁止任何缓存策策略,请求时服务器都要响应一个新的资源no-cache
不使用强缓存,直接去使用协商缓存,与no-cache
互斥,同时设置时,以`no-store为准max-age
:代表一个相对的时间长度,相对于客户端时间,单位是秒,例如Cache-Control:max-age=31536000
,意味着在成功请求的31536000秒后过期,每次请求成功会延迟失效时间s-maxage
:代理服务器缓存有效时间,public
情况下有效private
:默认值,只能被浏览器缓存public
:可以被浏览器缓存,也可以被代理服务器缓存,Expires:Mon, 20 Jul 2017 10:08:35 GMT
,在这个时刻之前都是有效的,请求成功不会延时失效时间,一般情况下都是使用Cache-Control
响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商(通过判断last-modified/if-modified-since是否一致
或者Etag/If-None-Match是否一致
),与服务器端对比判断资源是否进行了修改更新。服务端资源没有更改,则返回304.然后从浏览器获取资源,已更改则从服务器获取资源,返回200
实现协商缓存的两种方式:
Last-modified
:存在于响应头中,标识文件的最后修改时间If-modified-Since
:存在于请求头里面,值为之前返回的last-modified
上面一组属性可以解决大部分缓存情况,但是存在一些不足,他们的时间戳单位是秒,也就是说,如果发生修改资源的太快,在击几百毫秒之内完成,对于他们来说仍是相等的,无法识别出资源已经更新。另外也可能存在只改变文件名而不改变文件内容的情况,这种情况会被认定为资源更新,会去服务请资源而耗费性能。对于着二者的缺点,可以使用 Etag/If-None-Match
的方案优化
Etag
:存在于文件的哈希值,唯一的,资源改变会改变它的EtagIf-None-Match
:存在于请求头,值为之前返回的Etag
比较上面两种协商缓存的方案,他们都有一个共同流程,首次请求服务端返回一个标识放在响应头中,第二次及以后的请求都会将响应头的这个值放在请求头中,通过比较两个值来判断资源是否更改
这种方案并不能完全替代last-modified
,他只能作为一种补充,因为它同样存在一些不足,首先,文件的哈希值需要服务器去计算,对服务器造成了额外的开销,尤其对于一些大文件或者文件数目很多的情况,频繁计算文件哈希值造成了性能的而损耗。另外,生成etag的过程中存在精度问题,某些情况会造成比对失败
不同类型的文件缓存方案:
具体的缓存方案需要根据实际的开发场景来决定
刷新页面的行为
Cache-Control
会变成·no-chche
即不走强缓存cookie、localStorage、sessionStorage的使用
跨站脚本攻击,向客户端插入脚本,用户打开网页或者点击某个按钮会运行注入的脚本
参考于美团技术团队: 如何防止XSS攻击
script
标签<h1>前端渲染后台返回的数据: <script>alert(1)</script> </h1>
<script>
let backendData = alert(1) //后端的数据
let data = backendData //前端对这些数据进行操作
console.log(data)
</script>
后台返回的数据 "><script>alert(‘XSS‘);</script>
<input type="text" value="<%= getParameter("keyword") %>">
拼接后:
<input type="text" value=""><script>alert(‘XSS‘);</script>">
javascript:
等可执行代码。后台返回的数据:javascript:alert(‘XSS‘)
<a href="<%= escapeHTML(getParameter("redirect_to")) %>">跳转...</a>
拼接后
<a href="javascript:alert(‘XSS‘)">跳转...</a>
background-image:url("javascript:...");
的代码(新版本浏览器已经可以防范)。expression(...)
的 CSS 表达式代码(新版本浏览器已经可以防范)。根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM 型三种。对于前两种,后端应该做好防护,而第三种DOM型需要前端防范
对于存储型和反射性
他们都是从后台取出恶意代码,然后再html中被拼接,被浏览器执行,有两种方法预防:
改成纯前端渲染,把代码和数据分隔开。这在很多内部、管理系统中常用
.innerText
),还是属性(.setAttribute
),还是样式(.style
)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了对 HTML 做充分转义。采用合适的转义库,如 doT.js、ejs、FreeMarker 等,对 HTML 模板各处插入点进行充分的转义。把一些关键字符力例如& < > " ‘ /
等转义掉,HTML 的编码是十分复杂的,在不同的上下文里要使用相应的转义规则
对于DOM型
.innerHTML
、.outerHTML
、document.write()
时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent
、.setAttribute()
等,对于Vue/React 技术栈,尽量不使用 v-html
/dangerouslySetInnerHTML
功能,在前端 render 阶段避免 innerHTML
、outerHTML
的 XSS 隐患。DOM 中的内联事件监听器,如 location
、onclick
、onerror
、onload
、onmouseover
等,<a>
标签的 href
属性,JavaScript 的 eval()
、setTimeout()
、setInterval()
等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,其他防范措施
参考美团技术团队 如何防止CSRF攻击
跨站请求伪造,引导用户进入第三方网站中,然后发送请求,冒充用户身份,对被攻击的网站执行某些操作,
//从 bank.example 中拿到用户cookie
<img style="width:0;" src="http://bank.example/withdraw?amount=10000&for=hacker" >
<form method="POST" action="https://bank.example/xxx" enctype="multipart/form-data">
<input type="hidden" name="name" value="xiaoming"/>
<input type="hidden" name="amount" value="10000"/>
</form>
<script>
document.forms[0].submit();
</script>
<a href="http://bank.example/withdraw?amount=10000&for=hacker" taget="_blank">重磅消息!! <a/>
CSRF只是冒用cookie,并不能获取到cookie的实际值,另外,CSRF通常发生在第三方网站
同源检测
SameSite属性
SamesiteCookie是一个可能替代同源验证的方案,但目前还并不成熟,其应用场景有待观望。
SameSite=None
不做限制,浏览器会在同站请求、跨站请求下继续发送 cookiesSameSite=Strict
:只在访问相同站点时发送 cookieSameSite=Lax
:假如这个请求是这种请求(改变了当前页面或者打开了新页面)且同时是个GET请求,则这个Cookie可以作为第三方CookieJWT验证
其他防范措施
攻击者诱导受害者进入第三方网站,再第三方的网站中,向被攻击的网站发送请求,由于再第三方网站中,用户存在cookie,已经完成身份验证,所以在
参考文档 :使用Fetch
Fetch作为一种Http请求方案,是XHR的代替方案,注意Fetch是基于Promise原生的API,而Axios是基于Promise的库,Fetch使用方法与Axios十分类似,注意post请求时,fetch传递的时body属性,值是对象转化成字符串JSON.stringify(data)
首先要知道TCP三次握手的目的是什么:为了确保双方的发送和接收能力都是正常且可靠的
FIN
之后,服务端并不能及时的响应断开连接的请求FIN
,必须等到服务端所有的报文都发送完毕,这个过程需要一定时间。去除第二次服务端给客户端的回应的话,期间等待服务端发送完毕的过程中,长时间没回应的话,客户端会认为丢包,然后又给服务端发了一个FIN关闭请求,这时就会出现问题。正向代理是客户端和其他所有服务器(重点:所有)的代理者,而反向代理是客户端和反向代理服务器所代理的服务器之间的代理(也就是说反向代理有可能代理2个服务器,3个服务器等)
原文:https://www.cnblogs.com/baifangzi/p/15015938.html