一、HTTP协议简介
HTTP协议全称是Hyper Text Transfer Protocol,意为超文本传输协议,是用于从万维网服务器传输超文本到本地服务器的应用层协议。HTTP是无状态协议,基于TCP/IP通信协议传输数据。HTTP协议工作与客户端和服务器架构上,客户端浏览器通过URL向HTTP服务器也就是WEB服务器发起HTTP请求,WEB服务器接收请求处理完成后向客户端返回响应信息。
以下是HTTP通信过程的客户端和服务器交互图
1 - HTTP协议的特点
1)HTTP是无连接的。HTTP限制每次连接只处理一个请求。服务器处理完客户端请求并收到客户端应答后立即断开连接,采用这种方式可以节省传输时间;
2)HTTP是无状态的。HTTP协议是无状态协议,无状态指的是协议对于处理的事务没有记忆能力,意味着如果后续处理需要先前的信息,它必须重传,可能导致每次连接传送的数据量增大;
3)HTTP是媒体独立的。这意味着只要客户端和服务器知道如何处理指定类型数据的内容那么任何类型的数据都可以通过HTTP进行发送,客户端以及服务器指定使用适合的mime-type内容类型。
二、URI、URL和URN
1 - URI即uniform resource identifier,统一资源定位符,用来唯一标识一个资源,可以使用相对路径
Web上key的各种资源如HTML文档、图像、视频片段、程序都可以使用一个URI来定位
一般有三个部分组成:
1)主机名
2)标志符
指向资源的内部,通常以符号#开始伴随片段标识符结束
3)相对URI
相对URI通常不包含任何命名规范信息。它的路径通常指向同一台机器的资源,可能是相对路径
2 - URL即uniform resource locator,统一资源定位器,是一种特殊的URI,不仅可以标识资源还提供了唯一定位这个资源.HTTP就是使用URL进行数据传输和建立连接的。
以下以一个URL为例介绍URL的组成部分
示例URL:http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
对上面的URL解析,一个完整的URL应该包括以下几个部分:
1.协议部分:通常在开头,例如示例URL的协议http:代表本例使用的是HTTP协议,此外因特网还支持其它协议,如FTP、HTTPS等,协议之后是一个分隔符//;
2.域名部分:该URL的域名部分为“www.aspxfans.com”,也可以使用IP地址作为域名;
3.端口部分:跟在域名后面的就是端口8080,域名和端口部分之前使用“:”冒号隔开,端口不是一个URL协议必须部分,如果省略端口部分将采用默认端口;
4.虚拟目录部分:从域名或端口之后的第一个“/”到最后一个“/”为止包含最后一个是虚拟目录部分,本例子的虚拟目录部分是/news/;
5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”则是从域名后的最后一个“/”开始到“#”为止视为文件名部分,如果没有?和#那么从域名的最后一个/到结束都是文件名部分。本例中是“index.asp”。文件名也不是一个URL必须的部分,如果省略该部分则使用默认的文件名;
6.锚部分:从最后一个#开始到结束都是锚部分,本例的锚部分是name,锚部分也不是一个URL必须的部分。
3 - URN即uniform resource name,统一资源命名,用于通过名字标识资源,它命名资源却不提供资源定位。例如mailto:java-net@java.sun.com
URI、URL、URN三者的区别
URI是一种抽象的,高层次的概念定义统一资源标识。URN和URL都是具体的资源标识方式,简单来讲URN和URL都是特殊的URI,不是所有的URL都是URI,例如URN只提供资源标识却不提供资源定位,而URL两者都提供了。
三、HTTP请求消息结构
客户端发送一个HTTP请求消息到服务器,请求消息包括:请求行(request line)、请求头(request header)、空行和请求数据四个部分。
下面通过chrome浏览器抓取一个http请求进行分析:
> GET /j/new_search_subjects?sort=T&range=0,10&tags=&start=0&genres=%E5%96%9C%E5%89%A7 HTTP/1.1
> Host: movie.douban.com
> Accept-Encoding: gzip, deflate, br
> Accept-Language: zh-CN,zh;q=0.9
> User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.15 Safari/537.36
> Accept: application/json, text/plain, */*
> Referer: https://movie.douban.com/tag/
> Cookie: ll="118172"; bid=kJTa7SujWHs; __utma=30149280.2000124323.1533402721.1533402721.1533402721.1; __utmc=30149280; __utmz=30149280.1533402721.1.1.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; __utmt=1; __utmb=30149280.1.10.1533402721; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1533402723%2C%22https%3A%2F%2Fwww.douban.com%2F%22%5D; _pk_ses.100001.4cf6=*; __utma=223695111.328462105.1533402723.1533402723.1533402723.1; __utmb=223695111.0.10.1533402723; __utmc=223695111; __utmz=223695111.1533402723.1.1.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __yadk_uid=i4Wy6Y0Jf5LH2noie4vqhhueBJLyJBOM; _vwo_uuid_v2=D14F53571E3D8246FC30A7BBA7E761D45|e36fa49a5046511a8e08aeeaf7654892; _pk_id.100001.4cf6=70198d9ffe792ce5.1533402723.1.1533402736.1533402723.
> Connection: keep-alive
name=a
第一部分是请求行,用于说明请求类型,访问资源以及使用的http版本;
本例子的请求类型为get,http版本使用1.1
第二部分是请求头部,紧接着请求行之后的部分,用于说明服务器要使用的附加信息;
下表是常见的HTTP请求头信息说明:
请求头 | 说明 |
Host | 用于指定被请求资源的Internet主机和端口号,例如movie.douban.com |
User-Agent | 包含客户端操作系统、浏览器等信息 |
Accept-Encoding | 指定可接受的内容编码。Accept-Encoding: gzip, deflate, br |
Accept-Charset | 指定客户端接受的字符集 |
Accept-Language | 指定使用的自然语言 |
Referer | 用于判断来源页面https://movie.douban.com/tag/,经常用于图片防盗链 |
Cnnection | 当前连接是否保持,如Connection: keep-alive |
第三部分是空行,请求头部后面的空行是必须的;
第四部分是请求数据也叫请求主体request body;
四、HTTP响应消息
HTTP响应消息也由四部分组成,分别是状态行、响应头、空行和响应正文
下面通过一个http响应消息例子进行分析
HTTP/1.1 200 OK
Date: Sat, 04 Aug 2018 17:12:19 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=30
Vary: Accept-Encoding
X-Xss-Protection: 1; mode=block
X-Douban-Mobileapp: 0
Expires: Sun, 1 Jan 2006 01:00:00 GMT
Pragma: no-cache
Cache-Control: must-revalidate, no-cache, private
X-DAE-Node: brand57
X-DAE-App: movie
Server: dae
X-Content-Type-Options: nosniff
Content-Encoding: gzip
{"data":......}
第一部分是状态行,包括HTTP协议版本,状态码和状态消息;
本例这部分内容是HTTP/1.1 200 OK
第二部分是响应头,用于说明客户端使用的一些附加信息;
下表是常见的HTTP响应头信息的说明
响应头 | 说明 |
server | 使用的服务器名称 |
Content-Type | 返回响应的MIME类型和编码告诉浏览器服务器返回的数据属于什么文件类型 |
Content-Length | 响应体的数据长度 |
Content-Encoding | 与请求头Accept-Encoding对应,告诉浏览器服务器采用什么方式压缩编码 |
Content-Language | 描述资源采用的自然语言,与accept-language对应 |
Keep-Alive | 保持连接的时间,例如Keep-Alive: timeout=5,max=120 |
Expires | 过期时间,当前时间小于过期时间会直接使用缓存数据,HTTP1.1版本基本可以忽略 |
Cache-Control | 缓存控制规则 |
第三部分是空行,同样HTTP响应消息中响应头之后必须为空行;
第四部分是响应正文,主要是服务器返回给客户端的文本信息。例如json字符串或html字符串
五、常见的HTTP状态码
HTTP状态码主要由三个数字组成,第一个数字定义可响应类别,一共分为五种类别:
类别 | 类别描述 |
1** | 指示消息。服务器收到请求,需要请求者继续执行操作 |
2** | 成功。操作被成功接收并处理 |
3** | 重定向。需要进一步操作以完成请求 |
4** | 客户端错误。请求包含语法错误或者无法完成请求 |
5** | 服务器错误,服务器在处理请求过程中发生了错误 |
常见的HTTP状态码列表
状态码 | 状态码英文名称 | 中文描述 |
200 | OK | 请求成功 |
202 | Accepted | 已经接收请求但是未处理完成 |
302 | Found | 临时跳转,跳转地址由Location指定 |
304 | Not Modified | 未修改。请求资源未修改,服务器返回此状态不会返回任何资源,客户端直接访问客户端缓存资源 |
307 | Temporary Redirect | 临时重定向,与302类似使用GET请求重定向 |
400 | Bad Request | 客户端请求有语法错误,服务器无法理解 |
403 | Forbidden | 服务器收到请求但是拒绝提供服务 |
404 | Not Found | 请求资源不存在 |
405 | Method Not Allowed | 客户端请求方法被禁止 |
408 | Request Time-out | 客户端请求时间过长,超时 |
500 | ||
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
502 | Bad Gateway | 充当网关或者代理的服务器从远端服务器接收到无效请求,通常是由连接超时引起的 |
503 | Servce Uavailable | 由于超载或者系统维护,服务器暂时无法处理客户端请求 |
六、HTTP请求方法
HTTP1.1定义的可以使用的请求方法如下
请求方法 | 方法说明 |
GET | 请求指定的页面信息,返回实体主体,请求参数封装在URL中 |
POST | 向指定资源提交数据进行处理请求(例如上传文件或者表单),请求数据包含在请求主体中 |
HEAD | 类似GET请求,只是返回的响应没有具体内容,主要用于获取表头 |
PUT | 从客户端向服务器发送数据取代指定的文件的内容 |
DELETE | 请求服务器删除指定页面 |
CONNECT | HTTP/1.1协议中预留的能够将连接改为管道方式的代理服务器 |
OPTIONS | 允许客户端查看服务器的性能 |
TRACE | 回显服务器收到的请求,主要用于测试或者诊断 |
七、HTTP请求/响应过程
用户在客户端输入一个html页面的URL地址,按下回车一般会经历下面流程。
1、客户端浏览器向DNS服务器请求解析该URL中的域名所对应的IP地址;
2、客户端浏览器获取解析的IP地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
3、客户端浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP 请求,该请求报文作为TCP三次握手的第三个报文的数据发送给服务器;
4、服务器对浏览器请求作出响应,并把对应的html文本发送给浏览器;
5、释放TCP连接;
6、浏览器将返回的html文本渲染显示;
八、GET和POST请求的区别
1.GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,而POST方法是把提交的数据放在HTTP包的Body中;
2.GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制;
3.GET方式提交数据,会带来安全问题,比如一个登录页面,通过GET方式提交数据时,用户名和密码将出现在URL上,而POST请求是放在请求主体中请求数据不会直接被用户看到