HTTP协议详解(深⼊理解)
引⼊
超⽂本传输协议(HTTP,HyperText Transfer Protocol)是互联⽹上应⽤最为⼴泛的⼀种⽹络协议。所有的WWW⽂件都必须遵守这个标准。设计HTTP最初的⽬的是为了提供⼀种发布和接收HTML页⾯的⽅法。1960年美国⼈Ted Nelson构思了⼀种通过计算机处理⽂本信息的⽅法,并称之为超⽂本(hypertext),这成为了HTTP超⽂本传输协议标准架构的发展根基。Ted Nelson组织协调万维⽹协会(World Wide Web Consortium)和互联⽹⼯程⼯作⼩组(Internet Engineering Task Force )共同合作研究,最终发布了⼀系列的RFC,其中著名的RFC 2616定义了HTTP 1.1。
http协议的作⽤及特点
HTTP是⼀个客户端和服务器端请求和应答的标准(TCP)。客户端是终端⽤户,服务器端是⽹站。通过使⽤Web浏览器、⽹络爬⾍或者其它的⼯具,客户端发起⼀个到服务器上指定端⼝(默认端⼝为80)的HTTP请求。(我们称这个客户端)叫⽤户代理(user agent)。应答的服务器上存储着(⼀些)资源,⽐如HTML⽂件和图像。(我们称)这个应答服务器为源服务器(origin server)。在⽤户代理和源服务器中间可能存在多个中间层,⽐如代理,⽹关,或者隧道(tunnels)。尽管TCP/IP协议是互联⽹上最流⾏的应⽤,HTTP协议并没有规定必须使⽤它和(基于)它⽀持的层。事实上,HTTP可以在任何其
他互联⽹协议上,或者在其他⽹络上实现。HTTP只假定(其下层协议提供)可靠的传输,任何能够提供这种保证的协议都可以被其使⽤。
通常,由HTTP客户端发起⼀个请求,建⽴⼀个到服务器指定端⼝(默认是80端⼝)的TCP连接。HTTP服务器则在那个端⼝监听客户端发送过来的请求。⼀旦收到请求,服务器(向客户端)发回⼀个状态⾏,⽐如"HTTP/1.1 200 OK",和(响应的)消息,消息的消息体可能是请求的⽂件、错误消息、或者其它⼀些信息。HTTP使⽤TCP⽽不是UDP 的原因在于(打开)⼀个⽹页必须传送很多数据,⽽TCP协议提供传输控制,按顺序组织数据,和错误纠正。
通过HTTP或者HTTPS协议请求的资源由统⼀资源标⽰符(Uniform Resource Identifiers)(或者,更准确⼀些,URLs)来标识。
1.基于请求/响应模型的协议。请求和响应必须成对,先有请求后有响应
2.http协议默认端⼝:80
3.简单快速:客户向服务器请求服务时,只需传送请求⽅法和路径。请求⽅法常⽤的有GET、HEAD、POST。每种⽅法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模⼩,因⽽通信速度很快。
4.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
5.⽆连接:⽆连接的含义是限制每次连接只处理⼀个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采⽤这种⽅式可以节省传输时间。
6.⽆状态:HTTP协议是⽆状态协议。⽆状态是指协议对于事务处理没有记忆能⼒。缺少状态意味着如果后续处理需要前⾯的信息,则它必须重传,这样可能导致每次连接传送的数据量增⼤。另⼀⽅⾯,在服务器不需要先前信息时它的应答就较快。
协议功能
HTTP协议(HyperText Transfer Protocol,超⽂本传输协议)是⽤于从WWW服务器传输超⽂本到本地浏览器的传输协议。它可以使浏览器更加⾼效,使⽹络传输减少。它不仅保证计算机正确快速地传输超⽂本⽂档,还确定传输⽂档中的哪⼀部分,以及哪部分内容⾸先显⽰(如⽂本先于图形)等。
HTTP是客户端浏览器或其他程序与Web服务器之间的应⽤层通信协议。在Internet上的Web服务器上存放的都是超⽂本信息,客户机需要通过HTTP协议传输所要访问的超⽂本信息。HTTP包含命令和传输信息,不仅可⽤于Web访问,也可以⽤于其他因特⽹/内联⽹应⽤系统之间的通信,从⽽实现各类应⽤资源超媒体访问的集成。
我们在浏览器的地址栏⾥输⼊的⽹站地址叫做URL (Uniform Resource Locator,统⼀资源定位符)。就像每家每户都有⼀个门牌地址⼀样,每个⽹页也都有⼀个Internet地址。当你在浏览器的地址框中输⼊⼀个URL或是单击⼀个超级链接时,URL就确定了要浏览的地址。浏览器通过超⽂本传输协议(HTTP),将Web服务器上站点的⽹页代码提取出来,并翻译成漂亮的⽹页。
http协议的版本
HTTP/1.0,发送请求,创建⼀次连接,获得⼀个web资源,连接断开
HTTP/1.1,发送请求,创建⼀次连接,获得多个web资源,连接断开
Http协议的组成
Http协议由Http请求和Http响应组成,当在浏览器中输⼊⽹址访问某个⽹站时,你的浏览器会将你的请求封装成⼀个Http请求发送给服务器站点,服务器接收到请求后会组织响应数据封装成⼀个Http响应返回给浏览器。即没有请求就没有响应。
http请求包括:请求⾏、请求头、空⾏、请求体
http响应包括:响应⾏、响应头、空⾏、响应体
HTTP请求报⽂
HTTP请求报⽂由3部分组成(请求⾏+请求头+空⾏+请求体):
请求⾏:
例如:POST /chapter17/user.html HTTP/1.1
格式:请求⽅式资源路径协议/版本
请求⾏必须在http请求格式的第⼀⾏。
get请求:
将请求参数追加在url后⾯,不安全
url长度限制get请求⽅式数据的⼤⼩
没有请求体
⼀般的HTTP请求⼤多都是GET。
post请求:
请求参数在请求体处,较安全。
请求数据⼤⼩没有显⽰
只有表单设置为method=“post”才是post请求,其他都是get请求
常见get请求:地址栏直接访问、<a href="">、<img src="">等
HEAD请求:
HEAD跟GET相似,不过服务端接收到HEAD请求时只返回响应头,不发送响应内容。所以,如果只需要查看某个页⾯的状态时,⽤HEAD更⾼效,因为省去了传输页⾯内容的时间。
DELETE请求:
OPTIONS请求:
⽤于获取当前URL所⽀持的⽅法。若请求成功,会在HTTP头中包含⼀个名为“Allow”的头,值是所⽀持的⽅法,如“GET, POST”。
PUT请求:
把⼀个资源存放在指定的位置上。
本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有⼀个重要区别,PUT通常指定了资源的存放位置,⽽POST则没有,POST的数据存放位置由服务器⾃⼰决定。
TRACE请求:
回显服务器收到的请求,主要⽤于测试或诊断。
CONNECT请求:jsessionid
CONNECT⽅法是HTTP/1.1协议预留的,能够将连接改为管道⽅式的代理服务器。通常⽤于SSL加密服务器的链接与⾮加密的HTTP代理服务器的通信。
请求头:
例如:Host: 39.108.107.149:8080
请求头从第⼆⾏开始,到第⼀个空格结束。请求头和请求体之间存在⼀个空格,也叫空⾏(如下)
1 POST 39.108.107.149:8080/vk/app/rest/ddp/iModelServiceImpl/findModelByType HTTP/1.1
2 User-Agent: Fiddler
3 Host: 39.108.107.149:8080
4 Content-Length: 11
5
6 name=城市
请求头通常以键值对{key:value}⽅式传递数据。
key为规范的固定值
value为key对应的取值,通常是⼀个值,可能是⼀组。
HTTP请求报⽂头属性
常见请求头
Referer:表⽰这个请求是从哪个url跳过来的,通过百度来搜索淘宝⽹,那么在进⼊淘宝⽹的请求报⽂中,Referer的值就是:www.baidu。如果是直接访问就不会有这个头。
常⽤于:防盗链。
Referrer Policy: no-referrer-when-downgrade
Accept:告诉服务端,该请求所能⽀持的响应数据类型,专业术语称为MIME 类型(⽂件类型的⼀种描述⽅式)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
MIME格式:⼤类型/⼩类型[;参数]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
例如:
text/html,html⽂件
text/css,css⽂件
text/javascript,js⽂件
image/*,所有图⽚⽂件
if-Modified-Sincce:浏览器通知服务器,本地缓存的最后变更时间。与另⼀个响应头组合控制浏览器页⾯的缓存
Cokkie:客户端的Cookie就是通过这个报⽂头属性传给服务端的哦!
Cookie: JSESSIONID=15982C27F7507C7FDAF0F97161F634B5
这⾥就出了⼀个问题,⽹站A怎么保证⾃⼰请求体中保存的cookie就是⽹站A的cookie⽽不是⽹站B的cookie呢,这就和cookie⾥⾯的jsessionid有关系了,关于
cookie,session,sessionid,jsessionid的区别联系,可以参考这个博⽂:
User-Agent:浏览器通知服务器,客户端浏览器与操作系统相关信息
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Connection:表⽰客户端与服务连接类型;Keep-Alive表⽰持久连接,close已关闭
Connection: keep-alive
Host:请求的服务器主机名
Host: sczpkj.f3322:3000
Content-Length:请求体的长度
POST 39.108.107.149:8080/vk/app/rest/ddp/iModelServiceImpl/findModelByType HTTP/1.1
User-Agent: Fiddler
Host: 39.108.107.149:8080
Content-Length: 11
name=城市
Content-Type:请求的与实体对应的MIME信息。如果是post请求,会有这个头,默认值为application/x-www-form-urlencoded,表⽰请求体内容使⽤url编码
Content-Type: application/x-www-form-urlencoded
Accept-Encoding:浏览器通知服务器,浏览器⽀持的数据压缩格式。如GZIP压缩
Accept-Encoding: gzip, deflate
Accept-Language:浏览器通知服务器,浏览器⽀持的语⾔。各国语⾔(国际化i18n)
Accept-Language: zh-CN,zh;q=0.9
Cache-Control:指定请求和响应遵循的缓存机制
对缓存进⾏控制,如⼀个请求希望响应返回的内容在客户端要被缓存⼀年,或不希望被缓存就可以通过这个报⽂头达到⽬的。
更多请求头属性可以参考这篇⽂章:
请求体
当请求⽅式是post的时,请求体会有请求的参数,格式如下:
username=zhangsan&password=123
POST 39.108.107.149:8080/vk/app/rest/ddp/iModelServiceImpl/findModelByType HTTP/1.1
User-Agent: Fiddler
Host: 39.108.107.149:8080
Content-Length: 20
name=城市&status=1
HTTP响应报⽂
HTTP的响应报⽂也由三部分组成(响应⾏+响应头+空⾏+响应体)
⽰例:
1 HTTP/1.1 200 OK
2 Server: Apache-Coyote/1.1
3 Set-Cookie: JSESSIONID=E1352C5CCEAD7EA9A6F8DA253395781C; Path=/vk
4 Content-Type: application/json;charset=UTF-8
5 Transfer-Encoding: chunked
6 Date: Wed, 26 Sep 2018 03:24:59 GMT
7 //此处有空格
8 1dd0
9 {"sessionToken":null,"code":"1","msg":null,"service":"iModelServiceImpl","method":"findModelByType","key":null,"paras":{},"result":{"pageInfo":{"pageNum":1,"numPerPage":20,"totalCount":28,"pageNumShown":2,"startNum":0,"endNum":20},"l
10 0
响应⾏:
①报⽂协议及版本;
例如:
HTTP/1.1 200 OK
②状态码及状态描述;
状态码:由3位数字组成,第⼀个数字定义了响应的类别
1xx:指⽰信息,表⽰请求已接收,继续处理
2xx:成功,表⽰请求已被成功接受,处理。
200 OK:客户端请求成功
204 No Content:⽆内容。服务器成功处理,但未返回内容。⼀般⽤在只是客户端向服务器发送信息,⽽服务器不⽤向客户端返回什么信息的情况。不会刷新页⾯。
206 Partial Content:服务器已经完成了部分GET请求(客户端进⾏了范围请求)。响应报⽂中包含Content-Range指定范围的实体内容
3xx:重定向
301 Moved Permanently:永久重定向,表⽰请求的资源已经永久的搬到了其他位置。
302 Found:临时重定向,表⽰请求的资源临时搬到了其他位置
303 See Other:临时重定向,应使⽤GET定向获取请求资源。303功能与302⼀样,区别只是303明确客户端应该使⽤GET访问
307 Temporary Redirect:临时重定向,和302有着相同含义。POST不会变成GET
304 Not Modified:表⽰客户端发送附带条件的请求(GET⽅法请求报⽂中的IF…)时,条件不满⾜。返回304时,不包含任何响应主体。虽然304被划分在3XX,但和重定向⼀
⽑钱关系都没有
4xx:客户端错误
400 Bad Request:客户端请求有语法错误,服务器⽆法理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域⼀起使⽤。
403 Forbidden:服务器收到请求,但是拒绝提供服务
404 Not Found:请求资源不存在。⽐如,输⼊了错误的url
415 Unsupported media type:不⽀持的媒体类型
5xx:服务器端错误,服务器未能实现合法的请求。
500 Internal Server Error:服务器发⽣不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,⼀段时间后可能恢复正常,
响应头:
③响应报⽂头,也是由多个属性组成;
响应头也是⽤键值对k:v
服务器通过响应头来控制浏览器的⾏为,不同的头浏览器操作不同
常见请求头描述
Location指定响应的路径,需要与状态码302配合使⽤,完成跳转。
响应正⽂的类型(MIME类型)
Content-Type
取值:text/html;charset=UTF-8
通过浏览器以下载⽅式解析正⽂
Content-Disposition
取值:attachment;filename=xx.zip
Set-Cookie与会话相关技术。服务器向浏览器写⼊cookie
服务器使⽤的压缩格式
Content-Encoding
取值:gzip
Content-length响应正⽂的长度
定时刷新,格式:秒数;url=路径。url可省略,默认值为当前页。
Refresh
取值:3;url=www.itcast //三秒刷新页⾯到www.itcast
Server指的是服务器名称,默认值:Apache-Coyote/1.1。可以通过l配置进⾏修改。<Connector port="8080" ... server="itcast"/>
Last-Modified服务器通知浏览器,⽂件的最后修改时间。与If-Modified-Since⼀起使⽤。
Cache-Control 响应输出到客户端后,服务端通过该报⽂头属告诉客户端如何控制响应内容的缓存。常见的取值有常见的取值有
private 、public 、no-cache 、max-age ,no-store ,默认为private 。缓存时间为31536000秒(365天)
Content-Type 解释text/html html 格式text/plain 纯⽂本格式text/css CSS 格式text/javascript js 格式image/gif gif 图⽚格式image/jpeg jpg 图⽚格式image/png png 图⽚格式
application/x-www-form-urlencoded POST 专⽤:普通的表单提交默认是通过这种⽅式。form 表单数据被编码为key/value 格式发送到服务器。
application/json POST 专⽤:⽤来告诉服务端消息主体是序列化后的 JSON 字符串text/xml
POST 专⽤:发送xml 数据multipart/form-data
POST 专⽤:下⾯讲解
更多请求头属性可以参考这篇⽂章:响应体:
④响应报⽂体,服务器发送给浏览器的正⽂,即我们真正要的“⼲货” ;
响应体,响应体是服务器回写给客户端的页⾯正⽂,浏览器将正⽂加载到内存,然后解析渲染 显⽰页⾯内容
Content-Type 详解
前段时间在⼯作中负责接⼝的开发,使⽤到postman ⼯具调试接⼝,发现对http 理解⼀直不是很深⼊,下来⼜总结了⼀遍,发现很多东西确实是实践出真知。常见的Content-Type :
application/x-www-form-urlencoded
最常见的post 提交数据的⽅式。浏览器原⽣的form 表单,如果不设置enctype 属性,那么最终就会以application/x-www-form-urlencoded ⽅式提交数据⽰例:
1 POST 39.108.107.149:8080/vk/app/rest/ddp/iModelServiceImpl/findModelByType HTTP/1.1
2 Content-Type: application/x-www-form-urlencoded
3 cache-control: no-cache
4 Postman-Token: 8e602802-b4f5-4d05-96d7-e1c7a1951719
5 User-Agent: PostmanRuntime/7.1.1
6 Accept: */*
7 Host: 39.108.107.149:8080
8 cookie: JSESSIONID=6CD80B7028062D9190717CEE001C3194 9 accept-encoding: gzip, deflate 10 content-length: 32
11 Connection: keep-alive 12
13 name=%E5%9F%8E%E5%B8%82&status=1
⾸先,Content-Type 被指定为 application/x-www-form-urlencoded ;其次,提交的数据按照 key1=val1&key2=val2 的⽅式进⾏编码,key 和 val 都进⾏了 URL 转码。⼤部分服务端语⾔都对这种⽅式有很好的⽀持。
很多时候,我们⽤ Ajax 提交数据时,也是使⽤这种⽅式。例如 JQuery 和 QWrap 的 Ajax ,Content-Type 默认「application/x-www-form-urlencoded;charset=utf-8」。 multipart/form-data
这⼜是⼀个常见的 POST 数据提交的⽅式。我们使⽤表单上传⽂件时,必须让 form 的 enctyped 等于这个值。⽰例:
1 POST 39.108.107.149:8080/vk/app/rest/ddp/iDataSourcesBaseService/file HTTP/1.1
2 Content-Type: multipart/form-data; boundary=--------------------------629236571647111133881449
3 cache-control: no-cache
4 Postman-Token: 2146b4b3-2d30-469c-bbcd-fbc4693934d9
5 User-Agent: PostmanRuntime/7.1.1
6 Accept: */*
7Host: 39.108.107.149:8080
8cookie: JSESSIONID=6CD80B7028062D9190717CEE001C3194
9accept-encoding: gzip, deflate
10content-length: 435
11Connection: keep-alive
12
13----------------------------629236571647111133881449
14Content-Disposition: form-data; name="file"; filename=""
15Content-Type: text/plain
16
17test upload
18----------------------------629236571647111133881449
19Content-Disposition: form-data; name="extCode"
20
21test
22----------------------------629236571647111133881449
23Content-Disposition: form-data; name="extId"
24
253306
26----------------------------629236571647111133881449-- //结束标识
⾸先⽣成了⼀个 boundary ⽤于分割不同的字段,为了避免与正⽂内容重复,boundary 很长很复杂。然后 Content-Type ⾥指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容。
消息主体⾥按照字段个数⼜分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着内容描述信息,然后是回车,最后是最后是字段具体内容(⽂本或⼆进制),如果传输的是⽂件,还要包含⽂件名和⽂件类型信息。消息主体最后以 --boundary-- 标⽰结束。
上⾯提到的这两种 POST 数据的⽅式,都是浏览器原⽣⽀持的,⽽且现阶段原⽣ form 表单也只⽀持这两种⽅式。但是随着越来越多的 Web 站点,尤其是 WebApp,全部使⽤Ajax 进⾏数据交互之后,我们完全可以定义新的数据提交⽅式,给开发带来更多便利。
application/json
application/json 这个 Content-Type 作为响应头⼤家肯定不陌⽣。实际上,现在越来越多的⼈把它作为请求头,⽤来告诉服务端消息主体是序列化后的 JSON 字符串。由于JSON 规范的流⾏,除了低版本 IE 之外的各⼤浏览器都原⽣⽀持 JSON.stringify,服务端语⾔也都有处理 JSON 的函数,使⽤ JSON 不会遇上什么⿇烦。 JSON 格式⽀持⽐键值对复杂得多的结构化数据,这⼀点也很有⽤。
⽰例:
1 POST 39.108.107.149:8080/vk/app/rest/ddp/vkIndexsService/queryVkIndxs HTTP/1.1
2 Content-Type: application/json
3 cache-control: no-cache
4 Postman-Token: 5014bc39-0777-49d5-bb8a-73db9a981e49
5 User-Agent: PostmanRuntime/7.1.1
6 Accept: */*
7Host: 39.108.107.149:8080
8cookie: JSESSIONID=6CD80B7028062D9190717CEE001C3194
9accept-encoding: gzip, deflate
10content-length: 132
11Connection: keep-alive
12
13{
14"name":"828验证继承",
15"getresultType":"2",
16"createTime":"Tue Sep 11 2018 00:00:00 GMT+0800 (中国标准时间)"
17}
这种⽅案,可以⽅便的提交复杂的结构化数据,特别适合 RESTful 的接⼝。各⼤抓包⼯具如 Chrome ⾃带的开发者⼯具、Firebug、Fiddler,都会以树形结构展⽰ JSON 数据,⾮常友好。
响应输出到客户端后,服务端通过该报⽂头属告诉客户端如何控制响应内容的缓存。常见的取值有常见的取值有private、public、no-cache、max-age,no-store,默认为private。缓存时间为31536000秒(365天)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论