http协议请求报文和响应报文
一、HTTP的Request/Response
先看Request
消息(客户端发送)的结构, Request 消息分为3部分
第一部分叫请求行(Request line), 第二部分叫请求头(Request header),第三部分是报文主体(body). header和body之间有个空行。
1 | 请求行 = 请求方法 + 请求URI + HTTP版本号 |
再看Response
消息(服务器端发送)的结构,Response消息分为3部分
第一部分叫状态行,第二部分叫响应头,第三部分是响应主体,header和body之间有个空行。
1 | 状态行 = HTTP版本号 + 状态码 + 原因短语 |
当使用的是GET
方法的时候, body是为空的。
比如如下图
我们打开Fiddler 捕捉一个网页的Request 然后分析下它的结构, 在Inspectors tab下以Raw的方式可以看到完整的Request的消息
二、HTTP首部
一般有4种首部,分别是通用首部、请求首部、响应首部和实体首部。
1. 通用首部字段
Cache-Control
作用:这个是非常重要的规则
,用于控制缓存的行为。 这个用来指定Response-Request遵循的缓存机制
。各个指令含义如下
Cache-Control:max-age=10
强缓存,单位秒
Cache-Control:public
可以被任何对象所缓存(包括:发送请求的客户端,代理服务器,等等),即使是通常不可缓存的内容(例如,该响应没有max-age指令或Expires消息头)
Cache-Control:private
内容只缓存到私有缓存中
Cache-Control:no-cache
使用协商缓存,同 max-age=0
Cache-Control:no-store
直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源,可用于关闭缓存。
Connection
例如:Connection: keep-alive
当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
例如: Connection: close
代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
Date
作用: 生成消息的具体时间和日期
例如:Date: Sat, 11 Feb 2012 11:35:14 GMT
Pragma
作用:防止页面被缓存,在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一样
Pargma只有一个用法, 例如: Pragma: no-cache
Trailer
作用:报文末端的首部一览
Transfer-Encoding
作用:指定报文主体的传输编码方式
Upgrade
作用:升级为其他协议
Via
作用:代理服务器的相关信息
Warning
作用:错误通知
2. 请求首部字段
Accept
作用: 浏览器端可以接受的媒体类型
例如: Accept: text/html
代表浏览器可以接受服务器回发的类型为 text/html 也就是我们常说的html文档,
如果服务器无法返回text/html类型的数据,服务器应该返回一个406错误(not acceptable)
通配符 *
代表任意类型
例如 Accept: */*
代表浏览器可以处理所有类型,(一般浏览器发给服务器都是发这个)
Accept-Charset
作用:浏览器申明自己接收的字符集
,这就是本文前面介绍的各种字符集和字符编码,如gb2312,utf-8
(通常我们说Charset包括了相应的字符编码方案);
Accept-Encoding
作用: 浏览器申明自己接收的编码方法
,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate),(注意:这不是只字符编码);
例如: Accept-Encoding: gzip, deflate
Accept-Language
作用: 浏览器申明自己接收的语言
。
语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等;
例如: Accept-Language: en-us
Authorization
作用:Web认证信息。
Expect
作用:期待服务器的特定行为。
Form
作用:用户的电子邮箱地址
Host(发送请求时,该报头域是必需的)
作用: 请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的
例如: 我们在浏览器中输入:http://www.guet.edu.cn/index.html
浏览器发送的请求消息中,就会包含Host请求报头域,如下:
Host:http://www.guet.edu.cn
此处使用缺省端口号80,若指定了端口号,则变成:Host:指定端口号
If-Match
作用:比较实体标记(Etag)
If-Modified-Since
作用:比较资源的更新时间(与Last-Modified配合实现协商缓存)
If-None-Match
作用:比较实体标记(与Etag配合实现协商缓存)
If-Range
作用:资源未更新时发送实体Byte的范围请求
If-Unmodified-Since
作用:比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards
作用:最大传输逐跳数
Proxy-Authorization
作用:代理服务器要求客户端的认证信息
Range
作用:实体的字节范围请求
Referer
作用: 提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,比如从我主页上链接到一个朋友那里,他的服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。
例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
TE
作用:传输编码的优先级
User-Agent
作用:告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本。
我们上网登陆论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本
,你所使用的浏览器的名称和版本,这往往让很多人感到很神奇,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器
。
例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)
3. 响应首部字段
Accept-Ranges
作用:是否接受字节范围请求
Age
作用:推算资源创建经过时间
ETag
作用:资源的匹配信息。根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以标识资源的状态。 当资源发送改变时,ETag也随之发生变化。
Location
作用:令客户端重定向至指定URI
Proxy-Authenticate
作用:代理服务器对客户端的认证信息
Retry-After
作用:对再次发起请求的时机要求
Server
作用:指明HTTP服务器的软件信息
例如:Server: Microsoft-IIS/7.5
Vary
作用:代理服务器缓存的管理信息
WWW-Authenticate
作用:服务器对客户端的认证信息
4. 实体首部字段
Allow
作用:资源可支持的http方法
Content-Type
作用:WEB服务器告诉浏览器自己响应的对象的类型和字符集,
例如:
Content-Type: text/html; charset=utf-8
Content-Type:text/html;charset=GB2312
Content-Type: image/jpeg
Content-Length
指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程中,Content-Length的方式要预先在服务器中缓存所有数据,然后所有数据再一股脑儿地发给客户端。
例如: Content-Length: 19847
Content-Language
作用:实体主体的自然语言。
Content-Location
作用:替代对应资源的URI。
Content-MD5
作用:实体主体的报文摘要。
Content-Range
作用:实体主体的位置范围。
Content-Encoding
作用:实体主体适用的编码方式。
Cookie
作用: 最重要的header, 将cookie的值发送给HTTP 服务器
Expires
作用: http1.0中,浏览器会使用expires在指定过期时间内使用本地缓存,但是本地时间和服务器时间可能不一致,将导致出现问题,故在http1.1版本中使用max-age实现强缓存。
例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT
Last-Modified
作用: 用于指示资源的最后修改日期和时间。(实例请看上节的If-Modified-Since的实例)
例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT
X-AspNet-Version
作用:如果网站是用ASP.NET开发的,这个header用来表示ASP.NET的版本
例如: X-AspNet-Version: 4.0.30319
X-Powered-By
作用:表示网站是用什么技术开发的
例如: X-Powered-By: ASP.NET
三、 浏览器缓存
浏览器缓存详解:expires,cache-control,last-modified,etag详细说明
这两个不是同时出现的,last-modified是老的http标准就有的,ETag是后来的http标准里才有的,算是对modified的优化,解决了一些modified不能解决的问题。
主要是为了解决Last-Modified 无法解决的一些问题。
- 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。
- 某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。
- 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。
四、Cookie探究
Cookie是什么?
HTTP cookie,通常直接叫做cookie,是客户端用来存储数据的一种选项,它既可以在客户端设置也可以在服务器端设置。cookie会跟随任意HTTP请求一起发送。
获取cookie
通过document.cookie可以获取当前域名下的cookie。
获取到的cookie的格式为a=1; b=2; c=3
如何设置cookie?
1 | document.cookie = "name=value[; expires=GMTDate][; domain=domain][; path=path][; secure]" |
cookie的字段详解
字段 | 用处 |
---|---|
domain | 控制 cookie对「哪个域」有效,可以包含子域也可以不包含。例如,Domain选项中,可以是”.google.com.hk”(不包含子域,表示它对google.com.hk的所有子域都有效),也可以是”www.google.com.hk"(包含子域)。 |
path | 控制cookie发送的指定域的「路径」,默认为”/“,表示指定域下的所有路径都能访问。它是在域名的基础下,指定可以访问的路径。例如cookie设置为”domain=.google.com.hk; path=/webhp”,那么只有”.google.com.hk/webhp”及”/webhp”下的任一子目录如”/webhp/aaa”或”/webhp/bbb”会发送cookie信息,而”.google.com.hk”就不会发送,即使它们来自同一个域。 |
expires | 设置cookie的失效日期。设置GMT格式的日期(new Date().toGMTString())。如果设置一个过去的时间,这个cookie会被立即删除。 |
max-age | 新的http协议使用max-age代替expires,它表示cookie的生存时长,单位为秒。若 max-age 为负值,则cookie将在浏览器会话结束后失效,即 session,max-age的默认值为-1。若 max-age 为0,则表示删除cookie。但我在chrome测试,设置为负值会直接删除该cookie,设置为session才会在浏览器会话结束后失效。 |
httponly | 服务器端设置httponly后,存于浏览器的cookie只能由服务器端读取,前端不能通过document.cookie读取,可以减轻xss攻击的危害。前端无法设置httponly。 |
secure | 指定后,cookie只有在使用SSL连接(如HTTPS请求)时才会发送到服务器。注意:只有保证网页是https协议(或其他安全协议)请求的,才能客户端在客户端通过 js 去设置secure 类型的 cookie。 |
sameSite | 用来防止CSRF攻击和用户追踪。http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html |
cookie的优缺点
优点:兼容性好,用于存储身份认证信息会自动发送给服务器。
缺点:
- 安全性:由于cookie在HTTP中是明文传递的,其中包含的数据都可以被他人访问,可能会被篡改、盗用。
- 大小限制:cookie的大小限制在4KB左右,若要做大量存储显然不是理想的选择。
- 增加流量:cookie每次请求都会被自动添加到Request Header中,无形中增加了流量。cookie信息越大,对服务器请求的时间也越长。
cookie操作封装
【参考】
常用的本地存储——cookie篇