Apache详解(四)Http 协议及报文头部结构

Apache详解总目录

  1. Internet 和 http协议
  2. Httpd介绍和安装
  3. Httpd配置
  4. http报文格式
  5. WEB相关工具

4 http 协议及报文头部结构

浏览器访问网页的过程
在这里插入图片描述

http协议:http/0.9, http/1.0, http/1.1, http/2.0,http/3.0
http协议:stateless 无状态, 服务器无法持续追踪访问者来源

解决http协议无状态方法

  • cookie 客户端存放
  • session 服务端存放

http事务:一次访问的过程

  • 请求:request
  • 响应:response

HTTP报文结构

协议查看或分析的工具:tcpdump, wireshark,tshark

参考资料:https://developer.mozilla.org/zh-CN/docs/Web/HTTP

4.1 HTTP请求报文

在这里插入图片描述
request报文格式

<method> <request-URL> <version>
<headers>
<entity-body

范例:

GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: www.magedu.com
User-Agent: HTTPie/0.9.4

范例:

#post.html
<form action="index.html" method="POST">
username:<br>
<input type="text" name="username" >
<br>
password:<br>
<input type="text" name="password" >
<br><br>
<input type="submit" value="Submit">
</form>
4.2 HTTP响应报文

在这里插入图片描述

response报文格式

<version> <status> <reason-phrase>
<headers>
<entity-body>

范例:

HTTP/1.1 200 OK
Cache-Control: max-age=3, must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 07 Nov 2019 03:44:14 GMT
Server: Tengine
Transfer-Encoding: chunked
Vary: Accept-Encoding
Vary: Accept-Encoding, Cookie
4.3 HTTP报文格式详解
4.3.1 Method 方法

请求方法,标明客户端希望服务器对资源执行的动作,包括以下:

  • GET: 从服务器获取一个资源
  • HEAD: 只从服务器获取文档的响应首部
  • POST: 向服务器输入数据,通常会再由网关程序继续处理
  • PUT: 将请求的主体部分存储在服务器中,如上传文件
  • DELETE: 请求删除服务器上指定的文档
  • TRACE: 追踪请求到达服务器中间经过的代理服务器
  • OPTIONS:请求服务器返回对指定资源支持使用的请求方法
  • CONNECT:建立一个到由目标资源标识的服务器的隧道
  • PATCH:用于对资源应用部分修改

其中GET,HEAD,POST用得较多

4.3.2 version版本
HTTP/<major>.<minor>

范例:

HTTP/1.1
4.3.3 status 状态码

在这里插入图片描述
三位数字,标记请求处理过程中发生的情况

参考资料:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

http协议状态码分类

1xx:100-101 信息提示
2xx:200-206 成功
3xx:300-307 重定向
4xx:400-415 错误类信息,客户端错误
5xx:500-505 错误类信息,服务器端错误

http协议常用的状态码

200: 成功,请求数据通过响应报文的entity-body部分发送;OK
301: 请求的URL指向的资源已经被删除;但在响应报文中通过首部Location指明了资源现在所处的新位置;Moved Permanently
302: 响应报文Location指明资源临时新位置 Moved Temporarily
304: 客户端发出了条件式请求,但服务器上的资源未曾发生改变,则通过响应此响应状态码通知客户端;Not Modified
307:  浏览器内部重定向
401: 需要输入账号和密码认证方能访问资源;Unauthorized
403: 请求被禁止;Forbidden
404: 服务器无法找到客户端请求的资源;Not Found
500: 服务器内部错误;Internal Server Error
502: 代理服务器从后端服务器收到了一条伪响应,如无法连接到网关;Bad Gateway
503: 服务不可用,临时服务器维护或过载,服务器无法处理请求
504: 网关超时
4.3.4 reason-phrase原因短语

状态码所标记的状态的简要描述

4.3.5 headers首部字段头

首部字段包含的信息最为丰富。首部字段同时存在于请求和响应报文内,并涵盖 HTTP 报文相关的内容信息。使用首部字段是为了给客服端和服务器端提供报文主体大小、所使用的语言、认证信息等内容

首部字段是由首部字段名和字段值构成的,中间用冒号":”分隔字段值对应,即key/value 键/值对单个 HTTP 首部字段可以有多个值

参考资料:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

首部的分类

  1. 通用首部:请求报文和响应报文两方都会使用的首部
  2. 请求首部:从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、请求内容相关优先级等信息
  3. 响应首部:从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息
  4. 实体首部:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的的信息
  5. 扩展首部

通用首部

  • Date: 报文的创建时间
  • Connection:连接状态,如keep-alive, close
  • Via:显示报文经过的中间节点(代理,网关)
  • Cache-Control:控制缓存,如缓存时长
  • MIME-Version:发送端使用的MIME版本
  • Warning:错误通知

请求首部

  • Accept:通知服务器自己可接受的媒体类型

  • Accept-Charset: 客户端可接受的字符集

  • Accept-Encoding:客户端可接受编码格式,如gzip

  • Accept-Language:客户端可接受的语言

  • Client-IP: 请求的客户端IP

  • Host: 请求的服务器名称和端口号

  • Referer:跳转至当前URI的前一个URL

  • User-Agent:客户端代理,浏览器版本

    条件式请求首部

  • Expect:允许客户端列出某请求所要求的服务器行为

  • If-Modified-Since:自从指定的时间之后,请求的资源是否发生过修改

  • If-Unmodified-Since:与上面相反

  • If-None-Match:本地缓存中存储的文档的ETag标签是否与服务器文档的Etag不匹配

  • If-Match:与上面相反

    安全请求首部

  • Authorization:向服务器发送认证信息,如账号和密码

  • Cookie: 客户端向服务器发送cookie

    代理请求首部

  • Proxy-Authorization: 向代理服务器认证

响应首部

信息性:

  • Age:从最初创建开始,响应持续时长
  • Server:服务器程序软件名称和版本

协商首部:某资源有多种表示方法时使用

  • Accept-Ranges:服务器可接受的请求范围类型
  • Vary:服务器查看的其它首部列表

安全响应首部:

  • Set-Cookie:向客户端设置cookie
  • WWW-Authenticate:来自服务器对客户端的质询列表

实体首部

  • Allow: 列出对此资源实体可使用的请求方法

  • Location:告诉客户端真正的实体位于何处

  • Content-Encoding:对主体执行的编码

  • Content-Language:理解主体时最适合的语言

  • Content-Length: 主体的长度

  • Content-Location: 实体真正所处位置

  • Content-Type:主体的对象类型,如text

    缓存相关

  • ETag:实体的扩展标签

  • Expires:实体的过期时间

  • Last-Modified:最后一次修改的时间

4.3.6 entity-body实体

请求时附加的数据或响应时附加的数据,例如:登录网站时的用户名和密码,博客的上传文章,论坛上的发言等。

4.4 Cookie 和 session

在这里插入图片描述

无状态协议是指协议对事物处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它应答就很快。

HTTP是超本文传输协议,顾名思义,这个协议支持超文本的传输。什么是超文本?说白了就是使用HTML编写的页面。通常,我们使用客户端浏览器访问服务器的资源,最常见的URL也是以html为后缀的文件,因此可以说超文本是网络上最主要的资源。

既然HTTP协议的目的是在于支持超文本的传输,也就是资源的传输,那么客户端浏览器向HTTP服务器发送请求,继而HTTP服务器将相信资源发回给客户端这样一个过程中,无论对于客户端还是服务器,都没有必要记录这个过程,因为每一次请求和响应都是相对独立的,一般而言,一个URL对应着一个唯一的超文本,正是因为这样的唯一性,使得记录用户的行为状态变得毫无意义,所以,HTTP协议被设计为无状态的连接协议符合它本身的需求。

HTTP协议这种特性有优点也有缺点,优点在于解放了服务器,每一次请求"点到为止",不会造成不必要的连接占用,缺点在于如果为了保留状态,每次请求都会传输大量的重复信息内容。

可是随着 Web 的不断发展,很多业务都需要对通信状态进行保存.

如果是一次性会话的过程: 打开浏览器 -> 访问一些服务器内容 -> 关闭浏览器

但目前有很多WEB访问场景,并不是一次性会话,而是多次相关的会话,比如:

登录场景:打开浏览器 -> 浏览到登陆页面 -> 输入用户名和密码 -> 访问到用户主页(显示用户名) -> 修改密码(输入原密码)-> 修改收货地址…
问题:在此处登录会话过程中产生的数据(用户会话数据)如何保存下来呢?

购物场景:打开浏览器 -> 浏览商品列表 -> 加入购物车(把商品信息保存下来) -> 关闭浏览器
打开浏览器-> 直接进入购物车 -> 查看到上次加入购物车的商品 -> 下订单 -> 支付
问题: 在购物会话过程中,如何保存商品信息?

以上场景都需要保留会话数据,需要会话管理机制。

会话管理: 管理浏览器客户端和服务器端之间会话过程中产生的会话数据。

为了会话管理,HTTP就需要传输大量重复信息内容的问题,造成大量的网络带宽消耗。于是 Cookie 和 Session 技术闪亮登场了,它们可以为用户进行会话管理,实现保存状态。

4.4.1 Cookie

Cookie 又称为"小甜饼”。类型为"小型文本文件”,指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。由网景公司的前雇员卢·蒙特利在1993年3月发明

因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,所以Cookie就是用来绕开HTTP的无状态性的"额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。

在上面的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段Cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把Cookie发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段Cookie里追加新的商品信息。结帐时,服务器读取发送来的Cookie就行了。

在这里插入图片描述
set-cookie是首部字段

Cookie基于HTTP协议,也叫Web Cookie或浏览器Cookie,是服务器发送到用户浏览器并保存在客户端本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

Cookie主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

使用 Cookie 的状态管理

Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。当服务器收到HTTP请求时,服务器可以在响应头里面添加一个Set-Cookie选项。浏览器收到响应后通常会保存下Cookie,之后对该服务器每一次请求中都通过Cookie请求头部将Cookie信息发送给服务器。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息.另外,Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。

Set-Cookie首部字段

  • NAME=VALUE 赋予 Cookie 的名称和其值,此为必需项

  • expires=DATE Cookie 的有效期,若不明确指定则默认为浏览器关闭前为止

    会话期Cookie

    基于内存保存,会话期Cookie是最简单的Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。会话期Cookie不需要指定过期时间(Expires)或者有效期(Max-Age)。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期Cookie也会被保留下来,就好像浏览器从来没有关闭一样。

    持久性Cookie

    基于硬盘保存,和关闭浏览器便失效的会话期Cookie不同,持久性Cookie可以指定一个特定的过期时间(Expires)或有效期(Max-Age)。

    Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
                            过期时间
    

    提示:当Cookie的过期时间被设定时,设定的日期和时间只与客户端相关,而不是服务端。

  • path=PATH 指定了主机下的哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)。若不指定则默认为文档所在的文件目录,以字符 %x2F ("/") 作为路径分隔符,子路径也会被匹配。

    例如,设置 Path=/docs ,则以下地址都会匹配:

    • /docs
    • /docs/Web/
    • /docs/Web/HTTP
  • domain=域名 指定了哪些主机可以接受Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了Domain,则一般包含子域名。

    例如,如果设置 Domain=magedu.com,则Cookie也包含子域名(如:study.magedu.com)

  • Secure 标记为 Secure 的Cookie只应通过被HTTPS协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure 标记也无法提供确实的安全保障。从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)无法使用Cookie的 Secure 标记。

  • HttpOnly 加以限制使 Cookie 不能被 JavaScript 脚本访问,为避免跨域脚本 (XSS) 攻击,通过JavaScript的 Document.cookie API无法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。如果包含服务端 Session 信息的 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记

浏览器对cookie的限制

Cookie 存储的限制是不一样的。例如:单个域名可存储的 Cookie 数量、Cookie 大小等。

IE6.0IE7.0/8.0OperaFFSafariChrome
cookie个数每个域为20个每个域为50个每个域为30个每个域为50个没有个数限制每个域为53个
cookie大小4095个字节4095个字节4096个字节4097个字节4097个字节4097个字节

在进行页面 Cookie 操作的时候,应该尽量保证 Cookie 的个数小于 20 个,总大小小于 4KB,这是一个安全且保险的范围。

范例:响应报文中的set-cookie首部

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

范例:请求报文中的cookie首部字段

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

范例:响应报文set-cookie中的Secure 和 HttpOnly

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

范例:浏览器查看cookie

在这里插入图片描述

范例:chrome 浏览器禁止cookie
在这里插入图片描述
在这里插入图片描述

范例:php语言实现cookie的管理

#设置cookie
#cat setcookie.php
<?php
setcookie('title','cto'); #有效期为会话级
setcookie('user','wang',time()+3600*12); #有效期为12小时
echo "<h1>test setcookie </h1>"
?>
#说明:setcookie设置的cookie,只有下一次http请求才能生效

#显示cookie
cat showcookies.php
<?php
echo "<h1>test showcookie </h1>";
echo $_COOKIE["user"]; #显示user的这一个cookie
echo "<br />";
var_dump($_COOKIE); #显示所有cookie
//print_r($_COOKIE); #不如上面方式详细
?>

#删除cookie,通过设置过期时间实现
#vim delcookie.php
<?php
setcookie('user','cui',time()-3600*12);
echo "<h1>cookie:user is deleted </h1>";
?>

显示cookie
在这里插入图片描述

4.4.2 Sessio

在这里插入图片描述
session

session是相对于cookie的另外一个状态保持的解决方案,它是通过服务器来保持状态的。session指的是服务器上为每个客户端所开辟的独立存储空间,在其中保存的信息就是用于保存状态的。

Session是服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建session的方法。在创建了session的同时,服务器会为该session生成唯一的sessionId,而这个sessionId被创建了之后,就可以调用session相关的方法往session中增加内容了,而这些内容只会保存在服务器中,每个sessionid就像数据库中主键,可以根据SessionId 关联每个session的相关信息,比如:购物车里的商器,登录用户等。但发送给客户端浏览器的只有sessionId。当客户端浏览器再次发送http请求时,会自动地将这个sessionId 附加在请求报文中 ,服务器收到请求之后就会根据sessionId找到对应的session,从而再次使用,使得用户的状态得以保持。

每个session都有一个sessionId,这个ID存放有两种方式:

1、通过URL存取,比如:Java程序中,URL会带上一个jsessionId=xxxxxx等,这样每次重新请求的时候都传了sessionId给服务器

2、通过cookie存取(Tomcat默认如此),这种cookie是session cookie,区别于persistent cookies也就是我们常说的cookie,session cookie要注意的是存储在浏览器内存中,而不是写到硬盘上。程序一开始执行,服务器就生成一个sessionId并通过cookie携带客户端浏览器的缓存中,当下一次访问的时候,服务器先检测一下是否有这个cookie,如果有就取它的ID,如果没有就再生成一个。这就是为什么关闭浏览器之后,再进去session已经没有了,其实在服务器端session并没有清空,而是sessionId变了。

当将浏览器关闭,服务器保存的session数据不是立即释放的,此时数据还会存在一段时间(可以在程序中加以设置,Tomcat默认15分钟),只要我们知道那个sessionId,就可以继续通过请求获得此session的信息。session里面的数据都放在服务器端,通过sessionId保证不会访问错误,服务端自动对session进行管理,如果在规定的时间内没有访问,则释放掉这个session。

最后提两点:

1、sessionId通常是看不到的,但是当我们把浏览器的cookie禁止之后,Web服务器会采用URL重写的方式传递sessionId,这样就可以在地址栏看到sessionId了

2、session cookie不可以跨窗口使用,但可以跨同一个窗口的多个标签页。

范例:PHP的PHPSESSID

<?php
session_start();
echo session_id();
?>
#执行结果如下图

在这里插入图片描述

范例:JAVA的JSESSIONID

在这里插入图片描述
在这里插入图片描述

4.4.3 cookie和session比较

cookie和session的相同和不同:

  • cookie和session两者都是在服务器端生成
  • session 将数据信息保存在服务器端,可以是内存,文件,数据库等多种形式,cookie 将数据保存在客户端的内存或文件中
  • 单个cookie保存的数据不能超过4K,每个站点cookie个数有限制,比如IE8为50个、Firefox为50个、Opera为30个;session存储在服务器,没有容量限制
  • cookie存放在用户本地,可以被轻松访问和修改,安全性不高;session存储于服务器,比较安全
  • cookie有会话cookie和持久cookie,生命周期为浏览器会话期的会话cookie保存在缓存,关闭浏览器窗口就消失,持久cookie被保存在硬盘,知道超过设定的过期时间;随着服务端session存储压力增大,会根据需要定期清理session数据
  • session中有众多数据,只将sessionID这一项可以通过cookie发送至客户端进行保留,客户端下次访问时,在请求报文中的cookie会自动携带sessionID,从而和服务器上的的session进行关联

cookie缺点:

1、使用cookie来传递信息,随着cookie个数的增多和访问量的增加,它占用的网络带宽也很大,试想假如cookie占用200字节,如果一天的PV有几个亿,那么它要占用多少带宽?

2、cookie并不安全,因为cookie是存放在客户端的,所以这些cookie可以被访问到,设置可以通过插件添加、修改cookie。所以从这个角度来说,我们要使用sesssion,session是将数据保存在服务端的,只是通过cookie传递一个sessionId而已,所以session更适合存储用户隐私和重要的数据

session 缺点:

1、不容易在多台服务器之间共享,可以使用session绑定,session复制,session共享解决

2、session存放在服务器中,所以session如果太多会非常消耗服务器的性能
cookie和session各有优缺点,在大型互联网系统中,单独使用cookie和session都是不可行的

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值