admin 管理员组

文章数量: 1184232

http协议B站

                                                        前言

 

http例子:

  1. 输入url打开网页

  2. ajax获取数据

  3. img标签加载图片

 

cache-control

Cache-Control:max-age=100  ##设置对应的静态资源缓存100s(设置缓存过期时间为100s)

通过给Cache-Control

  1. 设置public、private来控制是只能在客户端进行缓存,还是可以通过代理服务器进行缓存

  2. 设置must-revalidate在缓存过期之后必须要到服务端验证过才能继续使用缓存

  1. 设置no-cache、no-store可以控制我们是否使用缓存

 

缓存验证:(缓存的可用性)

缓存是存储在客户端的,客户端并不知道服务端是否有改变缓存的这部分数据,缓存有时候就需要进行一个验证

  1. 通过last-modified配合if-modified-since进行验证

  1. 通过etag配合if-none-match来来进行验证

 

总结:

不要以为缓存知识只有Cache-Control:max-age=100 来设置过期时间,缓存是web服务中对性能提升最大的一环

所以深入理解http缓存对web开发不论是前端人员或者后端人员都非常重要

 

更多有意义的头(http的头)

  1. Content-Type、Content-Encoding等来约束数据类型

  2. cookie保持会话信息(常见的session方案就是通过cookie来进行一个实现)

  1. CORS实现跨域并保持安全性限制(如果跨域的服务对所有人进行开放,那么每个人都能进行访问,因此可能受到违法连接)

 

深入tcp

  1. 什么是三次握手

  2. https链接的创建过程,以及为什么https就是安全的

  3. 什么是长链接,为什么需要长链接

  4. http2的信道复用有为什么能提供性能

 

 

带来好处

  1. 对于后端开发,你能够打造性能更好的http服务

  2. 对于前端开发,你能够好得使用http的特性帮助你进行开发

  3. 能够帮助前后端更好的协作

 

基础:

  1. 知道HTTP概念,知道html是什么,浏览器是怎么样的一个东西,有web服务存在,浏览器通过和web服务沟通才能拿到数据

  2. 想要深入学习http

 


 

 

                                               浏览器输入url后http请求返回的完整过程

 

 

 

 

浏览器的api里面的一个performance,performance会记录所有的时间点,时间过程的消耗会通过api进行记录

可以知道哪一个时间点耗时很长,可以对此时间点进行优化

 

请求过程解析:(数据加载过程时间点)

  1. 发起请求:浏览器输入url -->

  2. redirect:浏览器记录这个地址已经永久的跳转到一个新的地址,所以一开始浏览器需要判断一下需不需要进行redirect以及要redirect到哪里 -->

  3. 看缓存(App cache):可能请求的资源已经缓存过了,要看app cache缓存里是否有,如果没有缓存就要去实际的服务器那边去请求资源---->

  4. DNS(DNS查找):因为输入的是域名,域名要对应成ip之后,我们才能真正的访问到服务器,需要查找域名对应的ip地址,这一步是dns解析--->

  5. TCP链接:DNS解析到了ip之后,要创建TCP链接,创建TCP链接要经过TCP的三次握手之后,才能真正的把链接创建起来,如果这个请求是https的,那么要创建一个https的链接,和TCP的三次握手不一样,中间要有一个保证安全的数据传输过程---->

  1. Request(发送请求包):链接创建好之后才发送一个http的请求数据包---->

  1. Response(接收响应)    :请求包发送之后,服务器接收到这个数据,进行一个数据操作之后,返回我们这个请求想要的内容,开始返回数据,返回数据之后,这个请求才真正的完成


                                                             

                                                                         网络协议分层

 

 

 

网络传输过程:

http协议在应用层上,但是基于传输层的TCP协议,ip是网络层

 

低三层(web应用不太涉及,了解一下)

  1. 物理层主要作用是定义物理设备如何传输数据(网卡、端口、网线传输数据)

  2. 数据链路层在通信的实体间建立数据链路连接   (010101)

  3. 网络层为数据在结点之间创建逻辑链路

 

传输层:

TCP协议,udp协议

  1. 向用户提供可靠的端到端(End-to-End)服务:建立了客户端到baidu服务端的链接之后,二者两端如何去传输数据,传输数据的方式是在这一层进行定义的,如传数据数据可能很小可能很大,如果传输的数据很大,不能一次性传输,要对数据进行分包、分片,传输到客户端之后,要组装数据,这一个过程的定义,是在传输层定义的

  1. 传输层向高层屏蔽了下层数据通信的细节:http协议是是实现在TCP/IP协议基础上的,http协议传输数据只需要在浏览器上输入一个url,就自动发送一些相关的数据到服务器端,服务器端解析请求数据返回结果给浏览器端,然后浏览器把页面显示出来,这一过程会涉及到数据的分片、和组装,和服务器创建链接过程这些内容高一层不需要知道

 

应用层:

  1. 为应用软件提供了很多服务:发送http请求,应用层提供http协议

  2. 构建于TCP协议之上

  3. 屏蔽网络传输相关细节


 

 

                                                                                http协议发展历史

 

第一个http协议版本:http/0.9

只有一个命令get

没有HEADER等描述数据的信息

服务器发送完毕,就关闭TCP连接:TCP连接与http请求是不一样的,在同一个TCP连接里可以发送很多个http请求,在http1.1协议里可以这么做,TCP连接对应多个http请求,http请求在某一个TCP连接里进行发送

 

 

第二个版本:HTTP/1.0

增加了很多命令

增加了status code和header:status code用来描述服务端处理某一个请求之后它的一个状态,header描述发送或请求相关的一些数据以及对数据操作的一些方法

多字符集支持、多部分发送、权限、缓存等:使用http请求,实现web服务

 

第三个版本:HTTP/1.1(广泛使用)

  1. 持久连接:不关闭TCP连接

  2. pipeline:在服务端对于进来的请求按照顺序进行内容的返回,所以前一个请求的等待时间非常长,而后一个请求处理的比加快,后一个请求不能先发送,需要等第一个请求发送完成之后才能进行发送,这部分时间就是串行和并行性能的差异就体现出来了,这种情况在http2.0中会进行优化

  1. 增加了host和其他的一些命令:有了host在同一台物理服务器可以跑多个不通的web服务,如一个js的服务,一个java的服务,通过host字段表示都是请求到这台物理服务器上,但是会区分请求的哪一个软件服务,这个头的好处是在同一个物理服务器或者集群可以部署不同的web进行使用,提高物理服务器的使用效率

 

第四个版本:http2

  1. 所有数据以二进制传输:在http1.1中大部分数据传输是通过字符串,与http1数据传输分片方式不通,在HTTP2中所有数据是以帧来传输

  2. 同一个连接里面发送多个请求不再需要按照顺序来处理(因为以帧来传输):可以同时返回第一个请求里的数据,再同时返回第二个请求里的数据,实现并行的效能,能够更大限度的去让整个web应用的传输效率有个质的提升

  1. 头信息压缩以及推送等提高效率的功能(http2就是为了解决http1性能低下的问题):

            ①.头信息压缩就是在http1中每一次发送请求和返回请求,它的http头都需要进行一个完整的发送和返回,这部分头信息里卖弄的很多内容,如header的字段,Content-Type、Cache-Control这些字段是以字符串的形式保存的,所以占用的带宽量会比较大,在http2中头信息进行了一个压缩,头压缩就可以有效地减少带宽的使用

            ②.推送的功能,http请求只能是客户端发起请求,服务端响应请求返回内容,客户端永远是主动发,服务端永远是被动方,在http2中有了推送的概念,服务端是可以主动发起一些数据传输的,解决问题,如web页面有一些css、js文件以链接的方式在html文本信息中显示,通过浏览器解析里面的内容之后,再根据这个链接里面包含的url地址再去请去对应的css、js文件,这就会包含一个顺序的问题,我们需要先请求到HTML的文本,然后再浏览器里面运行解析了这个HTML文本之后,我们才能去发送css、js的请求,在http2中有了推送的功能之后,在请求这个HTML的同时,可以主动把HTML里面所需要引用到的css、js文件推送到客户端,这样就是HTML和css、js文件发送顺序是并行的,而不是串行的,这样就能提高传输的效率和性能

 

https协议:是安全版本的http协议,实际使用内容和http1.1没有特别大的区别


 

 

                                                                   HTTP三次握手

 

TCP连接与http请求之间的一个关系

在客户端和服务器之间进行一个http请求发送和返回的过程当中,需要创建一个TCP connection,因为http不存在连接的概念,只有请求和响应的概念,请求和响应都是数据包,它们之间是要经过一个传输的通道,这个传输的通道就是在TCP里创建了一个从客户端发起和服务端接收的一个连接,这个连接是可以一直保存在这边的,http的请求是在这个连接的基础上去发送,这里就有个概念就是在TCP连接上可以发送多个HTTP请求的,在不同的版本里这个模式是不一样的:

在http1.0中这个连接是在http创建的时候就创建TCP连接,连接创建完之后请求发送过去服务器响应之后,这个TCP就关闭了

在http1.1中这个连接通过某种方式声明这个连接可以一直保持着这边,意思就是第一个请求发送完之后,这个TCP连接没有关闭,第二个请求过来时,还可以在这个TCP连接上发送,好处就是因为TCP连接在创建过程中有三次握手的消耗,(三次握手代表有三次网络传输,客户端发送一次,服务端返回一次,客户端再发送一次,才会创建TCP连接,才能发送http请求),TCP连接保持住第二次请求就没有三次握手的开销

在http2中的好处:在http2中的TCP连接上面的http请求是可以并发的,这就导致同一个用户对同一个服务器发起一个网页请求的时候,它只需要一个TCP连接(在长连接中单独讲解)

 

TCP的三次握手:

 

  1. 首先客户端发起一个,我要创建连接的一个数据包的请求发送到服务端,里面会有一个标志位叫SYN=1,SYN是一个标志位,就是说这是一个创建请求的数据包,Seq=一个数据,一般等于1

  2. 服务端接收到这个数据包之后,知道有个客户要和它创建连接,服务端就会开启一个TCP socket端口,然后返回给客户端一个数据包,里面有第一个SYN=1的标志位,ACK等于客户端seq=的数据+1,再一个seq(服务端的seq)

  1. 客户端拿到服务端的数据包之后,知道服务端允许我创建一个TCP连接,再发送ACK=服务端的seq+1,客户端的seq等于一个新的数字

  2. 进行三次握手的原因:为了防止服务端开启一些无用的连接,网络传输是有延时的,通过光纤或者中间代理商服务器来进行一个传输,传输的过程中客户端发起一个创建连接的请求,如果服务端就直接创建了连接,返回内容给服务端,数据包因为网络传输的原因丢失数据,客户端就一直没有接收到服务器返回到东西,客户端设置超时时间关闭连接,再发起一个新的连接请求,但是这个时候服务端不知道客户端有没有接收到它返回的信息,且客户端没有给服务端一个确认要创建还是要关闭这个请求,那么服务端的端口就会一直开启来等待客户端发送实际的请求数据,服务端会浪费资源端口,所以需要三次握手确认因为网络原因导致数据没有传输到,这个连接就关闭了,服务端不需要一直等待。

  3. 三次握手就是为了规避网络传输当中延时而导致的一些服务器开销的一些问题

 

三次握手数据包的详细内容:使用工具wirshark抓包分析

 

 

10.10.110.58是本机的IP地址,59616是本机的端口  443是服务器的一个端口

电脑和服务器之间有三个来回,就是找到同一样的一个端口的来回,就可以确认是三次握手的一个过程

  1. 客户端首先TCP发送了一个SYN标志位,seq=0

  2. 服务端返回TCP SYN,ACK ,Ack=(客户端seq)0+1

  3. 客户端发送ACK为第一个标志位 ,Seq=(服务端返回的Ack)1,  Ack=(服务端返回的seq)0+1

  1. 这样就完成了三次握手过程


 

 

 

                                                            URI、URL、URN

http协议使用的基本是URL

URI:

  1. 包含URL和URN它们统一的一个定义,全名Uniform Resource Identifier/统一资源标志符(定位某一个特定的资源而设计的)

①.URL用来定位一个web网站具体的某一个页面

②.从http/web角度这些名词定义主要是为了识别在互联网上一个固定位置它的资源所在的地方,用这种方式来标志了某一个资源之后,我们就可以通过一个链接的方式去找到这个资源,互联网中这些http协议或者ftp协议它们的主要某地就是为了找到某一资源,并且通过某种方式获得这个资源,如网页就是HTML的代码,通过url访问到了这个地址之后,url指代就是HTML代码的地方,返回HTML代码,并且把页面的内容显示出来

  1. 用来唯一标识互联网上的信息资源:

  1. 包含URL和URN:

URL:

全名Uniform Resource Locator/统一资源定位器(用来找到资源所在的位置,并且去访问它,得到它)

http://user:pass@host:80/path?query=string#hash

http://  定义以怎么样的方式/协议去访问资源,有不同的协议如ftp://  mailto://,这些协议服务的实现方式不同,通过不同的协议去访问服务,解析的方式也就不一样,这就是协议的重要性,定义了服务/发送方如何传输数据,服务如何解析数据

通过协议的名称://来定义了如何请这个资源

 

user:pass@表示我们访问了资源之后,如果这个资源需要有特定的身份才能去访问,可以加上user:pass@来指定我就是特定用户,且你的服务可以通过我的用户名和密码来进行一个认证,来表示我是真的这个用户而不是一个虚假的用户,这种方式在现在的web开发中不太用到,有更好的方式做用户认证,用户不安全

 

host/ip:定位服务器在互联网中的位置,互联网中定位一台机器最基础的就是IP,hostname可以是ip就可以通过ip直接找到这台机器,hostname或者是域名,域名通过DNS服务解析成IP然后定位到这台机器服务器

:80 是端口,每台服务器都有非常多的端口,在这台服务器上可以跑很多的web服务,web可以监听不同的端口,如果找这台物理服务器上某一个web服务上存放的资源,就要指定要找的哪个web服务,端口用来定位找到的那台服务器存放的许多web服务某一个具体的web服务,上线服务浏览器基本看不到端口,web服务默认访问是80端口,端口不方便用户记忆,一般发送到互联网上的服务都不带端口,直接通过域名访问

 

/path(路由):因为web服务中可能存放了很多的内容,具体要如何找到这个内容,通过路由(path)定位,相似于Linux的目录路径,从http定义来说这个路径应该是直接对应的web服务目录结构下路径,因为web应用变得复杂,很多数据存放到数据库中而不是对应磁盘上的某一个文件所在的位置,更多时候用来辨别url所要请求的数据,在程序里去判断,而不是对应一个目录结构的映射关系,这就是路由的定义及使用方式

 

query=string:这是一个搜索参数,请求的资源要如何进行一个搜索,查找,操作的方式,通过这个参数来传参

 

#hash:在http定义中代表前面的一整个url找到了一个文档,但如果这个文档很大,好几M都是文字,作为用户只想看到某一个段落,它代表文档里的而某一个片段,客户端看到的也是文档里的某一个片段,web开发hash做锚点的定位工具

 

此类格式都叫做URL,比如ftp协议

 

URN:(使用不多,了解即可)

  1. 永久统一资源定位符

url http服务如果某一个资源链接,资源搬了一个位置,导致请求访问这个链接,请求不到数据,如果访问一个不存在资源的链接会返回404,url不会告诉你这个资源被搬到哪个地方,怎样才能访问到想要访问的东西,URN就解决这个问题,出现这个情况,通过urn,即使资源搬了一个位置,可以通过同个urn访问到这个地方,如果把urn指向了这个资源,这个资源挪动位置还是会被找到

  1. 在资源移动之后还能被找到

  1. 目前还没有非常成熟的使用方案


 

 

                                                            HTTP报文格式

 

发起请求这端永远是主动的,发起请求之后,服务端才会给一个响应

 

请求报文格式:

http请求首行,首行并不属于http的headers,headers是另外一个区分的,在请求报文里首行里会包含请求方法,http的请求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT,它们有各自的语义,一个完成度非常高的web服务会对于不同的请求方法,对于同一个url会有不同的操作,就是请求方法的语义

GET:获取数据,最常见的一种请求方式,当客户端要从服务器中读取文档时,当点击网页上的链接或者通过在浏览器的地址栏输入网址来浏览网页的,使用的都是GET方式。GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。

POST:创建数据,使用POST方法可以允许客户端给服务器提供信息较多。

PUT:更新数据

DELETE:删除数据

HEAD:HEAD就像GET,只不过服务端接受到HEAD请求后只返回响应头,而不会发送响应内容。

 

这些定义只是一张纸上写的,就是告诉它应该这么做,但实际上完全可以不按照这个方法去实现web服务,比如想通过请求方法去实现更新数据,完全可以这么做,只不过没有遵照http协议语义化的定义去做,这么做的坏处是,一个不知情的人来访问服务的时候,可能做了一个他认为安全的操作,但是你这边直接把数据更新掉了,这就是语义存在的意义规范操作,http协议没有强约束实现最终请求的内容,只是从定义上告诉你应该这么做

 

请求报文首行里第二个部分是url,请求资源的地址,存放路由相关的东西,不包含http协议,这个地址要服务端发起请求的时候需要解析以及创建连接的过程,最后在发送请求的时候,这个连接已经创建完成了

 

首行的第三部分是http协议版本,现在版本一般1.1,有些HEAD没办法返回

 

head包含了传输的数据内容,描述客户端想要接收到的数据格式

 

响应报文格式:

首行第一部分,是http的协议版本

首行第二部分,是code  200 状态是ok,ok是200的状态

 

http head要和http body区分,body中间是完整的空行,不仅仅是换行

 

HTTP方法:

用来定义对于资源的操作:

常有get,post,put,delete等,规范api接口设计

从定义上讲有各自的语义

 

HTTP code:

定义服务器对请求的处理结果:结果是处理成功的,或者需要重定向的,或者发送的请求有问题(没有认证,服务器发现错误)

各个区间的code有各自的语义:100~199之间操作要持续进行接下来做其他事情,200~299操作是成功的,300~399 操作重定向,有别的方式获取数据,400~499之间代表发送的请求有问题,401发送请求没有做认证,500~599之间服务器出现错误

 

好的HTTP服务可以通过code判断结果:

从返回的code得知请求处理结果是怎么样的,接下来该怎么操作

 

大部分开发会回复200或者500,不管数据请求是正确或者错误都返回200再返回数据里标注请求正确或错误,没有根据http语义(建议根据语义)


 

 

                                    创建一个最简单的web服务

使用:nodejs,目的为了演示头信息传输过程,(直接下载安装,使用git bash平台,visual studio开发工具)

 

创建server.js文件

 

 

function 接受了两个参数 require(请求服务发送的内容都封装到require)和response(做返回内容的时候,使用对象进行操作,返回要返回的东西)

 

在浏览器上访问localhost:8888,返回内容代表成功


           

 

                                                     认识HTTP客户端

浏览器就是常用的http客户端

 

 

General就是http请求的首行,不属于headers内容,remote address也不属于http报文的相关内容,调试工具把它列出来了

 

response就是HTML的代码,就是浏览器请求返回的内容,浏览器把HTML文件渲染成正常网页,不属于http请求的范畴

 

curl命令

curl   baidu  ##给百度发送了一个请求,请求baidu 重定向到/

curl www.baidu

curl -v wwwbaidu

 

 


 

 

                                            CORS跨域请求的限制与解决

浏览器同域限制(跨域如何请求资源)

 

跨域概念

新建第二个server2.js与server.js内容相同,端口改成8887,创建test.html 模拟跨域场景

test.html

<html>

<title>Document</title>

<body>

 

</body>

<script>

  var xhr= new XMLHttpRequest()

  xhr.open('GET' 'http://127.0.0.1:8887/')

  xhr.send()

</script>

</html>

 

server.js

const http = require('http')

 

 

http.createServer(function (require,response) {

console.log('request come',request.url)

 

 

const html = s.readFileSync('test.html', 'utf8')  ##设置utf8会读取字符串,不设就读取二进制

response.writeHead(200, {

'Content-Type': 'test/html'  ##设置header格式

response.end('123')

}).listen(8888)

 

 

console.log('server listening on 8888')

8888服务提供了HTML,这个HTML给8887服务发送请求,这个请求是跨域请求

 

结果报错,没有设置Access-Control-Allow-Origin,这个允许跨域的头

 

 

server2.js

const http = require('http')

 

 

http.createServer(function (require,response) {

console.log('request come',request.url)

 

 

response.writeHead(200, {

'Access-Control-Allow-Origin': '*' 

response.end('123')

}).listen(8887)

 

 

console.log('server listening on 8887')

const http = require('http')

 

 

 

 

http.createServer(function (require,response) {

console.log('request come',request.url)

 

 

 

 

response.writeHead(200, {

'Access-Control-Allow-Origin': '*'

'Access-Control-Allow-Headers': 'X-Test-Cors'

response.end('123')

}).listen(8887)

 

 

 

 

console.log('server listening on 8887')

不管有没有返回头,浏览器都会向服务发送请求,浏览器在发送请求的时候不知道服务是否跨域,会发送请求并且接收返回内容,浏览器在接收数据反回时读取数据没有Access-Control-Allow-Origin头,会把请求返回的内容会忽略掉,并且在命令行报不能跨域的错

curl没有跨域的概念,任何请求都能发送并返回内容,且可以输出内容,浏览器有同域限制

 

cors域请求

允许方法,这三个使用时不需要域请求去验证,其他方法需要

get

head

post

 

允许Content-Type(请求限制)

text/plain

multipart/form-date

application/x-www-form-urlencoded

这三个HTML使用form表单alment可以设置的3种数据类型

 

其他限制

请求头限制

XMLHttpRequestUpload对象均没有注册任何事物监听器

请求中没有使用ReadableSteam对象

 

 


web与http

1、web服务通过httpd协议通信

2、http是Internet中的公共语言(语言?不是协议吗?)

http的工作原理:

1、web客户端与服务器是如何通信的?

2、(表示web内容的)资源来自何方?

3、web事物是怎样工作的?

4、http通信所使用的报文格式?

5、底层tcp网络通传输?

6、不同的http协议变体?(协议变体?)

7、internet安装大量的http架构组件中的一部分

 

本文标签: http协议B站