一、HTTP协议简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,它是一种用于分布式、协作式和web应用系统的应用层协议。
HTTP的发展是由蒂姆·伯纳斯-李于1989年在欧洲核子研究组织(CERN)所发起。
HTTP的标准制定由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet Engineering Task Force,IETF)进行协调,最终发布了一系列的RFC,其中最著名的是1999年6月公布的 RFC 2616,定义了HTTP协议中现今广泛使用的一个版本——HTTP 1.1。
2014年12月,互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。 HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP 1.1成为HTTP的实现标准。
主要特点
1.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。
2.灵活:HTTP允许传输任意类型的数据对象。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件等)。
3.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
4.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
5.支持B/S及C/S模式。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
二、HTTP工作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。
HTTP协议采用了请求/响应模型。
- 客户端向服务器发送一个请求报文,请求报文包含请求行、请求头部、空行和请求数据。
- 服务器收到客户端的请求会响应,响应的内容包括状态行、响应头部、空行和响应数据。
1、HTTP 请求/响应的步骤:
1. 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如:https://www.baidu.com/
2. 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文。
一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
3. 服务器接收请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。
一个响应由状态行、响应头部、空行和响应数据4部分组成。
4. 释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;
若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5. 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。
然后解析每一个响应头,响应头告知HTML文档的若干特殊信息和文档的字符集。
客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
2、HTTP请求报文
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
3、HTTP请求方法
根据HTTP标准,HTTP请求可以使用多种请求方法。
- HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
- HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
GET 向指定的资源发出“显示”请求,并返回实体主体。。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会创建新的资源或修改现有资源,或二者皆有。
PUT 向指定资源位置上传其最新内容。
DELETE 请求服务器删除Request-URI所标识的资源。
TRACE 回显服务器收到的请求,主要用于测试或诊断。
OPTIONS 允许客户端查看服务器的性能。可以使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
注意:
在HTTP协议中,方法名称是区分大小写的。
HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。
4、HTTP状态码
所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。
状态代码的第一个数字代表当前响应的类型:
- 1xx消息——请求已被服务器接收,继续处理
- 2xx成功——请求已成功被服务器接收、理解、并接受
- 3xx重定向——需要后续操作才能完成这一请求
- 4xx请求错误——请求含有词法错误或者无法被执行
- 5xx服务器错误——服务器在处理某个正确请求时发生错误
消息 | 描述 |
---|---|
100 Continue | 服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。 |
101 Switching Protocols | 服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。 |
消息 | 描述 |
---|---|
200 OK | 请求成功(其后是对GET和POST请求的应答文档。) |
201 Created | 请求被创建完成,同时新的资源被创建。 |
202 Accepted | 供处理的请求已被接受,但是处理未完成。 |
203 Non-authoritative Information | 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝。 |
204 No Content | 没有新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。 |
205 Reset Content | 没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。 |
206 Partial Content | 客户发送了一个带有Range头的GET请求,服务器完成了它。 |
消息 | 描述 |
---|---|
300 Multiple Choices | 多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。 |
301 Moved Permanently | 所请求的页面已经转移至新的url。 |
302 Found | 所请求的页面已经临时转移至新的url。 |
303 See Other | 所请求的页面可在别的url下被找到。 |
304 Not Modified | 未按预期修改文档。客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。 |
305 Use Proxy | 客户请求的文档应该通过Location头所指明的代理服务器提取。 |
306 Unused | 此代码被用于前一版本。目前已不再使用,但是代码依然被保留。 |
307 Temporary Redirect | 被请求的页面已经临时移至新的url。 |
消息 | 描述 |
---|---|
400 Bad Request | 服务器未能理解请求。 |
401 Unauthorized | 被请求的页面需要用户名和密码。 |
401.1 | 登录失败。 |
401.2 | 服务器配置导致登录失败。 |
401.3 | 由于 ACL 对资源的限制而未获得授权。 |
401.4 | 筛选器授权失败。 |
401.5 | ISAPI/CGI 应用程序授权失败。 |
401.7 | 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。 |
402 Payment Required | 此代码尚无法使用。 |
403 Forbidden | 对被请求页面的访问被禁止。 |
403.1 | 执行访问被禁止。 |
403.2 | 读访问被禁止。 |
403.3 | 写访问被禁止。 |
403.4 | 要求 SSL。 |
403.5 | 要求 SSL 128。 |
403.6 | IP 地址被拒绝。 |
403.7 | 要求客户端证书。 |
403.8 | 站点访问被拒绝。 |
403.9 | 用户数过多。 |
403.10 | 配置无效。 |
403.11 | 密码更改。 |
403.12 | 拒绝访问映射表。 |
403.13 | 客户端证书被吊销。 |
403.14 | 拒绝目录列表。 |
403.15 | 超出客户端访问许可。 |
403.16 | 客户端证书不受信任或无效。 |
403.17 | 客户端证书已过期或尚未生效。 |
403.18 | 在当前的应用程序池中不能执行所请求的 URL。这个错误代码为 IIS 6.0 所专用。 |
403.19 | 不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。 |
403.20 | Passport 登录失败。这个错误代码为 IIS 6.0 所专用。 |
404 Not Found | 服务器无法找到被请求的页面。 |
404.0 | (无)–没有找到文件或目录。 |
404.1 | 无法在所请求的端口上访问 Web 站点。 |
404.2 | Web 服务扩展锁定策略阻止本请求。 |
404.3 | MIME 映射策略阻止本请求。 |
405 Method Not Allowed | 请求中指定的方法不被允许。 |
406 Not Acceptable | 服务器生成的响应无法被客户端所接受。 |
407 Proxy Authentication Required | 用户必须首先使用代理服务器进行验证,这样请求才会被处理。 |
408 Request Timeout | 请求超出了服务器的等待时间。 |
409 Conflict | 由于冲突,请求无法被完成。 |
410 Gone | 被请求的页面不可用。 |
411 Length Required | "Content-Length" 未被定义。如果无此内容,服务器不会接受请求。 |
412 Precondition Failed | 请求中的前提条件被服务器评估为失败。 |
413 Request Entity Too Large | 由于所请求的实体的太大,服务器不会接受请求。 |
414 Request-url Too Long | 由于url太长,服务器不会接受请求。当post请求被转换为带有很长的查询信息的get请求时,就会发生这种情况。 |
415 Unsupported Media Type | 由于媒介类型不被支持,服务器不会接受请求。 |
416 Requested Range Not Satisfiable | 服务器不能满足客户在请求中指定的Range头。 |
417 Expectation Failed | 执行失败。 |
423 | 锁定的错误。 |
消息 | 描述 |
---|---|
500 Internal Server Error | 请求未完成。服务器遇到不可预知的情况。 |
500.12 | 应用程序正忙于在 Web 服务器上重新启动。 |
500.13 | Web 服务器太忙。 |
500.15 | 不允许直接请求 Global.asa。 |
500.16 | UNC 授权凭据不正确。这个错误代码为 IIS 6.0 所专用。 |
500.18 | URL 授权存储不能打开。这个错误代码为 IIS 6.0 所专用。 |
500.100 | 内部 ASP 错误。 |
501 Not Implemented | 请求未完成。服务器不支持所请求的功能。 |
502 Bad Gateway | 请求未完成。服务器从上游服务器收到一个无效的响应。 |
502.1 | CGI 应用程序超时。 · |
502.2 | CGI 应用程序出错。 |
503 Service Unavailable | 请求未完成。服务器临时过载或宕机。 |
504 Gateway Timeout | 网关超时。 |
505 HTTP Version Not Supported | 服务器不支持请求中指明的HTTP协议版本。 |
更多详细的参数,请查看
三、URL和URLConnection
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息。
URL是Uniform Resource Locator的简写,中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。
1、URL 的具体语法格式如下:
协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值&参数2=值2....#标志
以下面这个URL为例,介绍下普通URL的各部分组成:
1. 协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等。
2. // 层级URL标记符号(为[//],固定不变)
3. 用户名:密码@:访问资源需要的凭证信息(可省略)
4. 域名部分:该URL的域名部分为“baike.baidu.com”。一个URL中,也可以使用IP地址作为域名使用
5. 端口部分:域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
6. 虚拟目录部分(路径):从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。如:/item/http/
7. 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。
如:243074。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
8. 参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。如:?fromtitle=HTTP%E5%8D%8F%E8%AE%AE&fromid=1276942&fr=aladdin。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
9. 锚部分:从“#”开始到最后,都是锚部分。锚部分也不是一个URL必须的部分
2、URI和URL的区别
1. URI(Uniform Resource Identifier)统一资源标识符,用来唯一的标识一个资源地址。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的。
URI一般由三部组成:
- 访问资源的命名机制
- 存放资源的主机名
- 资源自身的名称,由路径表示,着重强调于资源。
2. URL(Uniform Resource Locator),统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL一般由三部组成:
- 协议(或称为服务方式)
- 存有该资源的主机IP地址(有时也包括端口号)
- 主机资源的具体地址。如目录和文件名等
3. URN(Uniform Resource Name),统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com。
URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL。这是因为 URI 还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。上面的 mailto、news 和 isbn URI 都是 URN 的示例。
在Java的URI中,一个URI实例可以代表绝对的,也可以是相对的,只要它符合URI的语法规则。而URL类则不仅符合语义,还包含了定位该资源的信息,因此它不能是相对的。
在Java类库中,URI类不包含任何访问资源的方法,它唯一的作用就是解析。相反,
在Java类库中,使用 java.net.URL类来表示URL,URL类可以打开一个到达资源的流。
3、 java.net.URL类
在 java.net 包中包含专门用来处理 URL 的 URL类,可以获得 URL 的相关信息。
URL 类的构造方法和常用方法:
//方法等具体查看API
public static void main(String[] args) throws IOException {
URL url = new URL("https://www.baidu.com");
//获取此的授权部分 URL 。
System.out.println(url.getAuthority());
//获取此 URL的文件名。
System.out.println(url.getFile());
//获取端口
System.out.println(url.getPort());
//获取主机
System.out.println(url.getHost());
//获得默认端口
System.out.println(url.getDefaultPort());
//获得路径
System.out.println(url.getPath());
//获取该 URL的userInfo部分。
System.out.println(url.getUserInfo());
}
4、java.net.URLConnection 类
在 java.net 包中,定义了专门的 URLConnection 类来表示与 URL 建立的通信连接。
URLConnection对象通过 URL 类的 openConnection() 方法获得。
注意:我们在应用程序和URL链接的时候,使用URLConnection类。
当我们HTTP和URL连接的时候,使用URLConnection类的子类HttpURLConnection。
URLConnection 类的主要方法:
get和post使用: Java 使用GET和POST方式提交HttpURLConnection请求
参考文章:更多方法查看API
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。