title: 超文本传输协议 HTTP
date: 2016-01-08 22:14:00
categories:
- 网络
- 网络协议
tags:
- 网络
- 网络协议
- HTTP
permalink: /pages/d58ebc/
**超文本传输协议(HTTP)**是一个用于传输超媒体文档(例如 HTML)的应用层协议。
**超文本传输协议(HTTP)**是一个用于传输超媒体文档(例如 HTML)的应用层协议。HTTP 是 浏览器与服务器之间的数据传送协议。HTTP 遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待它收到服务器端响应。HTTP 是无状态协议,这意味着服务器不会在两个请求之间保留任何数据(状态)。该协议虽然通常基于 TCP/IP 层,但可以在任何可靠的传输层上使用;也就是说,不像 UDP,它是一个不会静默丢失消息的协议。
HTTP 是由 IETF(Internet Engineering Task Force,互联网工程工作小组) 和 W3C(World Wide Web Consortium,万维网协会) 共同合作制订的,它们发布了一系列的RFC(Request For Comments),其中最著名的是 RFC 2616,它定义了HTTP /1.1。
HTTP1.0 和 HTTP 1.1 主要区别如下:
HTTP/2 在 HTTP/1.1 有几处基本的不同:
HTTP 工作于 Client/Server 模型上。
客户端和服务器之间的通信采用 request/response 机制。
客户端是终端(可以是浏览器、爬虫程序等),服务器是网站的 Web 服务器。
一次 HTTP 操作称为一个事务,其工作过程大致可分为四步:
影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。
**带宽:**如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。
延迟:
HTTP 是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
一个 HTTP"客户端"是一个应用程序(Web 浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个 HTTP 的请求的目的。
一个 HTTP"服务器"同样也是一个应用程序(通常是一个 Web 服务,如 Apache Web 服务器或 IIS 服务器等),通过接收客户端的请求并向客户端发送 HTTP 响应数据。
HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
一旦建立连接后,数据消息就通过类似 Internet 邮件所使用的格式[RFC5322]和多用途 Internet 邮件扩展(MIME)[RFC2045]来传送。
以下是使用 wireshark 抓取的一个实际访问百度首页的 HTTP GET 报文:
可以清楚的看到它的层级结构如下图,经过了层层的包装。
客户端发送一个 HTTP 请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。
HTTP 请求报文由以下元素组成:
GET
, POST
或者一个名词像OPTIONS
,HEAD
来定义客户端的动作行为。通常客户端的操作都是获取资源(GET 方法)或者发送HTML form表单值(POST 方法),虽然在一些情况下也会有其他操作。http://
),domain(developer.mozilla.org
),或是 TCP 的port(HTTP 一般在 80 端口)。根据 HTTP 标准,HTTP 请求可以使用多种请求方法。
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT方法。
方法 | 描述 |
---|---|
GET | 请求指定的页面信息,并返回实体主体。 |
HEAD | 类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
DELETE | 请求服务器删除指定的页面。 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
OPTIONS | 允许客户端查看服务器的性能。 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
HTTP 请求消息头
请求消息头 | 说明 |
---|---|
Accept | 浏览器支持的格式 |
Accept-Encoding | 支持的编码格式,如(UTF-8,GBK) |
Accept-Language | 支持的语言类型 |
User-Agent | 浏览器信息 |
Cookie | 记录的是用户当前的状态 |
Referer | 指从哪个页面单击链接进入的页面 |
HOST | 目的地址对应的主机名 |
Connection | 连接类型。如 Keep-Alive 表示长连接,不会断开 |
Content-Length | 内容长度 |
Content-Type | 内容类型 |
HTTP 响应报文包含了下面的元素:
响应消息头 | 说明 |
---|---|
Allow | 服务器支持哪些请求方法(如 GET、POST 等)。 |
Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到 Content-Type 头指定的内容类型。利用 gzip 压缩文档能够显著地减少 HTML 文档的下载时间。Java 的 GZIPOutputStream 可以很方便地进行 gzip 压缩,但只有 Unix 上的 Netscape 和 Windows 上的 IE 4、IE 5 才支持它。因此,Servlet 应该通过查看 Accept-Encoding 头(即 request.getHeader("Accept-Encoding"))检查浏览器是否支持 gzip,为支持 gzip 的浏览器返回经 gzip 压缩的 HTML 页面,为其他浏览器返回普通页面。 |
Content-Length | 表示内容长度。只有当浏览器使用持久 HTTP 连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStram,完成后查看其大小,然后把该值放入 Content-Length 头,最后通过byteArrayStream.writeTo(response.getOutputStream() 发送内容。 |
Content-Type | 表示后面的文档属于什么 MIME 类型。Servlet 默认为 text/plain ,但通常需要显式地指定为 text/html。由于经常要设置 Content-Type,因此 HttpServletResponse 提供了一个专用的方法 setContentType。 |
Date | 当前的 GMT 时间。你可以用 setDateHeader 来设置这个头以避免转换时间格式的麻烦。 |
Expires | 应该在什么时候认为文档已经过期,从而不再缓存它? |
Last-Modified | 文档的最后改动时间。客户可以通过 If-Modified-Since 请求头提供一个日期,该请求将被视为一个条件 GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个 304(Not Modified)状态。Last-Modified 也可用 setDateHeader 方法来设置。 |
Location | 表示客户应当到哪里去提取文档。Location 通常不是直接设置的,而是通过 HttpServletResponse 的 sendRedirect 方法,该方法同时设置状态代码为 302。 |
Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过 response.setHeader("Refresh", "5;URL=http://host/path") 让浏览器读取指定的页面。 注意这种功能通常是通过设置 HTML 页面 HEAD 区的 <META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path"> 实现,这是因为,自动刷新或重定向对于那些不能使用 CGI 或 Servlet 的 HTML 编写者十分重要。但是,对于 Servlet 来说,直接设置 Refresh 头更加方便。 注意 Refresh 的意义是"N 秒之后刷新本页面或访问指定页面",而不是"每隔 N 秒刷新本页面或访问指定页面"。因此,连续刷新要求每次都发送一个 Refresh 头,而发送 204 状态代码则可以阻止浏览器继续刷新,不管是使用 Refresh 头还是 <META HTTP-EQUIV="Refresh" ...> 。 注意 Refresh 头不属于 HTTP 1.1 正式规范的一部分,而是一个扩展,但 Netscape 和 IE 都支持它。 |
Server | 服务器名字。Servlet 一般不设置这个值,而是由 Web 服务器自己设置。 |
Set-Cookie | 设置和页面关联的 Cookie。Servlet 不应使用response.setHeader("Set-Cookie", ...) ,而是应使用 HttpServletResponse 提供的专用方法 addCookie。参见下文有关 Cookie 设置的讨论。 |
WWW-Authenticate | 客户应该在 Authorization 头中提供什么类型的授权信息?在包含 401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"") 。 注意 Servlet 一般不进行这方面的处理,而是让 Web 服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。 |
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。
HTTP 状态码的英文为 HTTP Status Code
。
下面是常见的 HTTP 状态码:
HTTP 状态码分类
HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP 状态码共分为 5 种类型:
分类 | 分类描述 |
---|---|
1xx | 信息响应。服务器收到请求,需要请求者继续执行操作 |
2xx | 成功响应。操作被成功接收并处理 |
3xx | 重定向。需要进一步的操作以完成请求 |
4xx | 客户端错误。请求包含语法错误或无法完成请求 |
5xx | 服务器错误。服务器在处理请求的过程中发生了错误 |
更详细的 HTTP 状态码可以参考:
HTTP 是明文传输,HTTPS 通过 SSL\TLS 进行了加密
HTTP 的端口号是 80,HTTPS 是 443
HTTPS 需要到 CA 申请证书,一般免费证书很少,需要交费
HTTPS 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。
由于 Http 是一种无状态的协议,服务器单从网络连接上无从知道客户身份。
会话跟踪是 Web 程序中常用的技术,用来跟踪用户的整个会话。常用会话跟踪技术是 Cookie 与 Session。
HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器,并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳定的状态信息成为了可能。
Cookie 主要用于以下三个方面:
注:Cookie 功能需要浏览器的支持,如果浏览器不支持 Cookie 或者 Cookie 禁用了,Cookie 功能就会失效。
Java 中把 Cookie 封装成了 javax.servlet.http.Cookie
类。
Cookies
通常设置在 HTTP 头信息中(虽然 JavaScript 也可以直接在浏览器上设置一个 Cookie)。
设置 Cookie 的 Servlet 会发送如下的头信息:
HTTP/1.1 200 OK
Date: Fri, 04 Feb 2000 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT;
path=/; domain=w3cschool.cc
Connection: close
Content-Type: text/html
正如您所看到的,Set-Cookie
头包含了一个名称值对、一个 GMT 日期、一个路径和一个域。名称和值会被 URL 编码。expires
字段是一个指令,告诉浏览器在给定的时间和日期之后"忘记"该 Cookie。
如果浏览器被配置为存储 Cookies,它将会保留此信息直到到期日期。如果用户的浏览器指向任何匹配该 Cookie 的路径和域的页面,它会重新发送 Cookie 到服务器。浏览器的头信息可能如下所示:
GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)
Host: zink.demon.co.uk:1126
Accept: image/gif, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: name=xyz
不同于 Cookie 保存在客户端浏览器中,Session 保存在服务器上。
由于 Cookie 以明文的方式存储在本地,而 Cookie 中往往带有用户信息,这样就造成了非常大的安全隐患。
Session 的出现解决了这个问题,Session 可以理解为服务器端开辟的存储空间,里面保存了用户的状态,用户信息以 Session 的形式存储在服务端。当用户请求到来时,服务端可以把用户的请求和用户的 Session 对应起来。那么 Session 是怎么和请求对应起来的呢?答案是通过 Cookie,浏览器在 Cookie 中填充了一个 Session ID 之类的字段用来标识请求。
Session 工作流程是这样的:
服务器在创建 Session 的同时,会为该 Session 生成唯一的 Session ID,当浏览器再次发送请求的时候,会将这个 Session ID 带上,服务器接受到请求之后就会依据 Session ID 找到相应的 Session,找到 Session 后,就可以在 Session 中获取或者添加内容了。而这些内容只会保存在服务器中,发到客户端的只有 Session ID,这样相对安全,也节省了网络流量,因为不需要在 Cookie 中存储大量用户信息。该 Cookie 为服务器自动生成的,它的 maxAge
属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。
那么 Session 在何时何地创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同的创建 Session 的方法。Tomcat 的 Session 管理器提供了多种持久化方案来存储 Session,通常会采用高性能的存储方式,比如 Redis,并且通过集群部署的方式,防止单点故障,从而提升高可用。同时,Session 有过期时间,因此 Tomcat 会开启后台线程定期的轮询,如果 Session 过期了就将 Session 失效。
Cookie vs. Session 对比如下:
ASCII
字符串,如果需要存取 Unicode
字符或二进制数据,需要进行UTF-8
、GBK
或BASE64
等方式的编码。maxAge
属性为一个很大的数字。JESSIONID
的 Cookie,而 Cookie JESSIONID
的 maxAge
默认为-1,只要关闭了浏览器该 Session 就会失效,因此,Session 不能实现信息永久有效的效果。使用 URL 地址重写也不能实现。response.encodeURL(StringURL)
或response.encodeRediretURL(String URL)
进行 URL 地址重写,否则导致 Session 会话跟踪失效。此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。