HTTP协议报文
Http协议报文分为【Http请求报文】和【Http响应报文】
HTTP请求报文
Http请求报文由【请求行】、【请求头】、【请求空行】和【请求体】4个部分组成。
请求行
请求行由【请求方法】、【URL】和【HTTP协议版本】3个字段组成,它们用【空格分隔】。
比如 GET /data/info.html HTTP/1.1
HTTP常用方法
- GET方法:获取资源
- POST方法:传输实体
- PUT方法:传输文件
- HEAD方法:获取报文首部
- DELETE方法:删除文件
- OPTIONS方法:询问支持的方法
HTTP协议版本
HTTP0.9
最初的版本,只有一个命令GET,服务器只能回应HTML格式字符串。
HTTP1.0
- 引入了新的命令POST和HEAD(http数据头部)命令
每个TCP连接只能发送一个请求,发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。- 头信息是 ASCII 码,后面数据可为任何格式。服务器回应时会告诉客户端,数据是什么格式,即Content-Type字段的作用。这些数据类型总称为MIME即多用途互联网邮件扩展,每个值包括一级类型和二级类型,预定义的类型,也可自定义类型。
HTTP1.1
新增方法:PUT、PATCH、OPTIONS、DELETE
引入了持久连接(persistent connection),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。对于同一个域名,大多数浏览器允许同时建立6个持久连接引入了管道机制,即在同一个TCP连接里,客户端可以同时发送多个请求,进一步改进了HTTP协议的效率
同一个TCP连接里,所有的数据通信是按次序进行的。服务器只能顺序处理回应,前面的回应慢,会有许多请求排队,造成"队头堵塞"(Head-of-line blocking)
为避免上述问题,两种方法:一是减少请求数,二是同时多开持久连接
HTTP2.0
HTTP2.0是SPDY(谷歌公司研发的https的一种协议)的升级版
- 头信息和数据体都是二进制,称为头信息帧和数据帧( HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多。二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。)
- 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,避免了“队头堵塞“,此双向的实时通信称为多工(Multiplexing)
- 引入头信息压缩机制(header compression),头信息使用gzip或compress压缩后再发送;客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,不发送同样字段,只发送索引号,提高速度(HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。)
- HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送(server push)
HTTP1.0和HTTP1.1的区别
- 长连接
HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,弥补了HTTP1.0每次请求都要创建连接的缺点- 缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略- 带宽优化和网络连接的使用
HTTP1.0中,存在一些浪费带宽的现象,例如:客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),方便了开发者自由的选择以便于充分利用带宽和连接- 错误通知的管理
在HTTP1.1中新增24个状态响应码,如409(Conflict)表示请求的资源与资源当前状态冲突;.410(Gone)表示服务器上的某个资源被永久性的删除- Host头处理
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)
HTTPS与HTTP的一些区别
- 【CA证书收费】HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- 【SSL/TLS -> TCP】HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- 【443 -> 80】HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- 【防劫持】HTTPS可以有效的防止运营商劫持,解决了防劫持的一个大问题。
请求头
HTTP客户程序(例如浏览器),向服务器发送请求的时候必须指明请求类型(一般是GET或者 POST)。
如有必要,客户程序还可以选择发送其他的请求头。大多数请求头并不是必需的,但对于POST请求来说 Content-Length必须出现。
常见的请求头字段含义
- Accept: 浏览器可接受的MIME类型。
- Accept-Charset:浏览器可接受的字符集。
- Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。
- Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。
- Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中。
- Content-Length:表示请求消息正文的长度。
- Host: 客户机通过这个头告诉服务器,想访问的主机名。Host头域指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
- If-Modified-Since:客户机通过这个头告诉服务器,资源的缓存时间。只有当所请求的内容在指定的时间后又经过修改才返回它,否则返回304“Not Modified”应答。
- Referer:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的(防盗链)。包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
- User-Agent:User-Agent头域的内容包含发出请求的用户信息。浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。
- Cookie:客户机通过这个头可以向服务器带数据,这是最重要的请求头信息之一。
- Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。
- Connection:处理完这次请求后是否断开连接还是继续保持连接。如果Servlet看到这里的值为“Keep- Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
- Range:Range头域可以请求实体的一个或者多个子范围。例如,表示头500个字节:bytes=0-499表示第二个500字节:bytes=500-999表示最后500个字节:bytes=-500表示500字节以后的范围:bytes=500-第一个和最后一个字节:bytes=0-0,-1同时指定几个范围:bytes=500-600,601-999但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。
- UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。
请求空行
它的作用是通过一个空行,告诉服务器请求头部到此为止。
请求体
若方法字段是GET,则此项为空,没有数据若方法字段是POST,则通常来说此处放置的就是要提交的数据
常见的POST BODY格式
application/x-www-form-urlencoded
POST的默认格式,适合传输ascii字符,短字节
使用js中URLencode转码方法。包括将name、value中的空格替换为加号;将非ascii字符做百分号编码;将input的name、value用‘=’连接,不同的input之间用‘&’连接。
百分号编码什么意思呢。比如汉字‘丁’吧,他的utf8编码在十六进制下是0xE4B881,占3个字节,把它转成字符串‘E4B881’,变成了六个字节,每两个字节前加上百分号前缀,得到字符串“%E4%B8%81”,变成九个ascii字符,占九个字节(十六进制下是0x244534254238253831)。
把这九个字节拼接到数据包里,这样就可以传输“非ascii字符的 utf8编码的 十六进制表示的 字符串的 百分号形式”。同样使用URLencode转码,这种post格式跟get的区别在于,get把转换、拼接完的字符串用‘?’直接与表单的action连接作为URL使用,所以请求体里没有数据;而post把转换、拼接后的字符串放在了请求体里,不会在浏览器的地址栏显示,因而更安全一些。
multipart/form-data
适合传输长字节
对于一段utf8编码的字节,用application/x-www-form-urlencoded传输其中的ascii字符没有问题,但对于非ascii字符传输效率就很低了(汉字‘丁’从三字节变成了九字节),因此在传很长的字节(如文件)时应用multipart/form-data格式。smtp等协议也使用或借鉴了此格式。
multipart/form-data将表单中的每个input转为了一个由boundary分割的小格式,没有转码,直接将utf8字节拼接到请求体中,在本地有多少字节实际就发送多少字节,极大提高了效率,适合传输长字节。
raw
application/json用来告诉服务端消息主体是序列化的JSON字符串text/xml
binary
指的就是一些二进制文件类型。
如application/pdf,指定了特定二进制文件的MIME类型。
就像对于text文件类型,若没有特定的子类型(subtype),就使用 text/plain。
类似的,二进制文件没有特定或已知的 subtype,即使用 application/octet-stream,这是应用程序文件的默认值,一般很少直接使用 。
对于application/octet-stream,只能提交二进制,而且只能提交一个二进制,如果提交文件的话,只能提交一个文件,后台接收参数只能有一个,而且只能是流(或者字节数组)。
很多web服务器使用默认的 application/octet-stream 来发送未知类型。出于一些安全原因,对于这些资源浏览器不允许设置一些自定义默认操作,导致用户必须存储到本地以使用。一般来说,设置正确的MIME类型很重要。GraphQl
图状数据查询语言
HTTP响应报文
Http响应报文由【响应行】、【响应头】和【响应体】3个部分组成。
响应行
响应行一般由【HTTP协议版本】、【状态码】及其【描述】组成
比如 HTTP/1.1 200 OK
响应头
响应头用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会儿它回送的数据。
设置HTTP响应头往往和状态码结合起来。例如,有好几个表示“文档位置已经改变”的状态代码都伴随着一个Location头,而401(Unauthorized)状态代码则必须伴随一个WWW-Authenticate头。
然而,即使在没有设置特殊含义的状态代码时,指定响应头也是很有用的。响应头可以用来完成:设置Cookie,指定修改日期,指示浏览器按照指定的间隔刷新页面,声明文档的长度以便利用持久HTTP连接,……等等许多其他任务。
常见的响应头字段含义
- Allow:服务器支持哪些请求方法(如GET、POST等)。
- Content- Type:表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置 Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。
- Content-Length:表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。
- Set-Cookie:设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。
- Location:这个头配合302状态码使用,用于重定向接收者到一个新URI地址。表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。【Date】:当前的GMT时间,例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
- Server:服务器通过这个头告诉浏览器服务器的类型。Server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。Servlet一般不设置这个值,而是由Web服务器自己设置。
- Refresh:告诉浏览器隔多久刷新一次,以秒计。
- Expires:告诉浏览器把回送的资源缓存多长时间,-1或0则是不缓存。
- Content-Encoding:文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE4、IE5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept- Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
- Last-Modified:文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
- Transfer-Encoding:告诉浏览器数据的传送格式。
- WWW-Authenticate:客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\”executives\”“)。注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问。
注:设置响应最常用的方法是HttpServletResponse的setHeader,该方法有两个参数,分别表示响应头的名字和值。和设置状态代码相似,设置响应头应该在发送任何文档内容之前进行。
setDateHeader 设置包含日期的响应头 避免了把Java时间转换为GMT时间字符串
setIntHeadr 设置包含整数值的响应头 避免了把整数转换为字符串
HttpServletResponse还提供了许多设置
setContentType:设置Content-Type头。大多数Servlet都要用到这个方法。
setContentLength:设置Content-Length头。对于支持持久HTTP连接的浏览器来说,这个函数是很有用的。addCookie:设置一个Cookie(Servlet API中没有setCookie方法,因为应答往往包含多个Set-Cookie头)。
响应体
响应体就是响应的消息体,如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码,如果是JS就是JS代码,如此之类。
Chrome Network常用功能
General
- Request URL:请求的URL
- Request Method:请求使用的方法
- Status Code:响应状态码
- Remote Address:远程服务器的地址和端口
- Reffer Policy:Referrer判别策略
Response Header
- Date:标识产生响应的时间
- Content-Encoding:指定响应内容编码
- Server:包含服务器信息,如名称,版本号等
- Content-Type:文档类型,指出返回的数据类型是什么。如此处的text/html代表返回的是HTML代码
- Set-Cookie:设置Cookies。响应头中的Set-Cookie告诉浏览器要将此内容放在Cookies中,下次请求携带Cookies请求
- Expires:指定响应过期时间,可以使代理服务器将加载的内容更新到缓存当中。如果再次访问,就可直接从缓存中加载,降低服务器的负载,缩短加载时间。
Request Headers
- Accept:请求报头域,用于指定客户端可接受哪些信息类型
- Accept-Encoding:指定客户端可接受的语言类型
- Accept-Language:指定客户端可接受的内容编码
- Host:指定请求资源的主机IP和端口号,其为请求URL的原始服务器或网关的位置
- Cookie:网站为了辨别用户进行会话跟踪而储存在用户本地的数据。主要功能是维持当前访问会话。(非常重要!!!)
- Referer:用来标识这个请求是从哪个网页过来的。服务器拿到这一信息并做相应的处理,如来源统计,防盗链等
- User-Agent:一个特殊的字符串头,可以使服务器识别客户使用的操作系统及版本等信息。在做爬虫时一定要加上此信息
- Content-Type:互联网媒体类型,在HHTP协议消息中,用来表示具体请求中的媒体信息类型
Preview
Response preview 响应预览
在Preview(预览功能)中,控制台会把发送过来的json数据自动转换成javascript的对象格式。
Response
Raw Response Data 原始响应数据
原始响应数据
Initiator
Request initiator call stack 请求发起方调用栈
Timing
- Queueing(排队):浏览器在以下情况下将请求排队:
有更高优先级的请求。
已为该来源打开了六个TCP连接。仅适用于HTTP/1.0和HTTP/1.1。
浏览器正在磁盘缓存中短暂分配空间 - Stalled:出于Queueing中描述的任何原因,该请求都可能被暂停
- DNS Lookup:浏览器正在解析请求的IP地址
- Proxy negotiation:浏览器正在与代理服务器协商请求
- Request sent:请求发送时间
- ServiceWorker Preparation:浏览器正在启动service worker
- Request to ServiceWorker:请求发送到service worker的时间
- Waiting (TTFB): 浏览器等待第一个字节响应的时间
- Content Download:响应内容下载时间
- Receiving Push:浏览器正在通过HTTP/2服务器推送接收此响应的数据
- Reading Push: 浏览器正在读取先前接收的本地数据。
Cookies
Request and response cookies 请求/响应Cookies
show filtered out request cookies
显示被过滤的Cookie
SameSite
用来限制第三方 Cookie,从而减少安全风险
- Strict
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。 - Lax (默认)
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。 - None
Chrome 将Lax变为默认设置。网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。