参考文献:
定义
HTTP全称超文本传输协议,是应用层协议。在上网浏览网页的时候,浏览器和web服务器之间就会通过HTTP在Internet上进行数据的发送和接收。HTTP是一个基于请求/响应(Request/Response)模式的、无状态协议。
特点
-
支持客户端/服务器模式(C/S系统)
-
通信速度快:客户向服务器请求服务时,只需传送请求方法和路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快;
-
传输类型多样:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记;
-
无连接:无连接是指限制每次连接只处理一个请求。服务器处理完客户端的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间;
-
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续要用到前面的数据需要重传。在身份验证的时候,每次请求都要传递身份信息很浪费资源。
HTTP的请求
HTTP的请求报文分为三个部分:请求行、请求头、请求体。
请求报文
HTTP请求格式
|
||||||
请求行
|
请求方法(Method)
|
空格
|
请求地址(Path)
|
空格
|
协议版本
|
\r\n
|
请求头
|
header1 |
:
|
value1 |
|
|
\r\n
|
header2 |
:
|
value2 |
|
|
\r\n
|
|
header…… |
:
|
value……
|
|
|
\r\n
|
|
headerN
|
:
|
valueN
|
|
|
\r\n
|
|
空行
|
\r\n
|
|||||
请求体
|
请求体
|
|||||
-
请求行(分为三部分)
1.请求方法:
一共有八种:
-
GET:向指定的资源发出“显示”请求,使用GET方法应该只用在读取数据上;
-
POST:指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求文本中,这个请求可能会创建新的资源或者修改现有资源,或者两者都有;
-
PUT:向指定资源位置上传其最新内容;
-
DELETE:请求服务器删除Request-URI所标识的资源;
-
OPTIONS:使服务器传回该资源所支持的所有HTTP请求方法。用*代替资源名称,向web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作,跨域请求时会用到;
-
HEAD:于GET方法类似都是向服务器发出指定资源的请求,只不过服务器将不传回资源的文本部分。它的好处在于使用这个方法可以在不必传输全部内容的情况下,就可以获取其中关于该资源的信息。
-
TRACE:显示服务器收到的请求,主要用于测试或者诊断;
-
CONNECT:HTTP/1.1中预留给能够将连接改为通道方式的代理服务器。通常用于SSL加密服务器的链接。
如果是RESTful接口的话一般会用到PUT(增)、DELETE(删)、GET(查)、POST(改)。
P.S. 什么是RESTful(https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/08.3.md)
2.请求地址
3.协议版本
-
请求头
请求头可用于传递一些附加信息,格式是键值对 键:值,注意冒号后面有一个空格。
请求和响应常见通用的Header:
名称
|
作用
|
Content-Type
|
请求体/响应体的类型,eg:text/plain、application/json
|
Accept
|
说明接收的类型,可以多个值,用,(英文逗号)隔开
|
Content-length
|
请求体/响应体的长度,单位是字节
|
Content-Encoding
|
请求体/响应体的编码格式,eg:gzip、deflate
|
Accept-Encoding
|
告知对方我方接受的Content-Encoding
|
ETag
|
给当前资源的标识,eg:Last-Modified、If-None-Match、If-Modified-Since配合,用于缓存控制
|
Cache-Control
|
取值一般是no-cache、max-age=xxx,xxx为整数,表示资源缓存有效期(秒)
|
常见的请求Header:
名称
|
作用
|
Authorization
|
用于设置身份认证信息
|
User-Agent
|
用户标识,如:OS和浏览器的类型和版本
|
If-Modified-Since
|
值为上一次服务器返回的Last-Modified值,用于确定某个资源是否被更改过,没有更改过就从缓存中读取
|
If-None-Match
|
值为上一次服务器返回的ETag值
|
Cookie
|
已有的Cookie
|
Referer
|
标识请求引用自哪个地址,比如你从页面A跳转到页面B时,值为页面A的地址
|
Host
|
请求的主机和端口号
|
-
请求体
请求体/请求正文是POST请求方式中的请求参数,以键值对的形式进行存储,多个请求参数之间用&连接,如果请求当中请求体,那么在请求头当中的Content-Length属性记录的就是该请求体的长度。
根据应用场景的不同,HTTP请求的请求体有三种不同的形式。
第一种:移动开发者常见的,请求体是任意类型的,服务器不会解析请求体,请求体的处理需要自己解析。
HTTP请求格式
|
||||||
请求行
|
请求方法(Method)
|
空格
|
请求地址(Path)
|
空格
|
协议版本
|
\r\n
|
请求头
|
header1
|
:
|
value1
|
|
|
\r\n
|
header2
|
:
|
value2
|
|
|
\r\n
|
|
header……
|
:
|
value……
|
|
|
\r\n
|
|
headerN
|
:
|
valueN
|
|
|
\r\n
|
|
空行
|
\r\n
|
|||||
请求体
|
请求体
|
|||||
第二种:第二种和第三种都有固定的格式,是服务器端开发人员最先了解的两种。这里的格式要求就是URL中Query String的格式要求:多个键值对之间用&连接,键与值之间用=连接,且只能用ASCII字符,非ASCII字符需要使用UrlEncode编码。
HTTP请求格式
|
||||||
请求行
|
请求方法(Method)
|
空格
|
请求地址(Path)
|
空格
|
协议版本
|
\r\n
|
请求头
|
header1
|
:
|
value1
|
|
|
\r\n
|
header2
|
:
|
value2
|
|
|
\r\n
|
|
Content-Type
|
:
|
Application/x-www-form-urlencoded
|
|
|
\r\n
|
|
header……
|
:
|
value……
|
|
|
\r\n
|
|
headerN
|
:
|
valueN
|
|
|
\r\n
|
|
空行
|
\r\n
|
|||||
请求体
|
key1=value1&key2=value2
|
|||||
第三种:第三种请求体被分成多个部分,文件上传时会被使用,这种格式最线是被用于邮件传输中,每个字段/文件都被boundary(Content-Type中指定的)分成单独的段,每段以——加boundary开头,然后是该段的描述头,描述头之后空一行接内容,请求结束的标识为boundary后面加— —。
HTTP请求格式
|
||||||
请求行
|
请求方法(Method)
|
空格
|
请求地址(Path)
|
空格
|
协议版本
|
\r\n
|
请求头
|
header1
|
:
|
value1
|
|
|
\r\n
|
header2
|
:
|
value2
|
|
|
\r\n
|
|
Content-Type
|
:
|
multipart/form-data;boundary={boundary}
|
|
|
\r\n
|
|
header……
|
:
|
value……
|
|
|
\r\n
|
|
headerN
|
:
|
valueN
|
|
|
\r\n
|
|
空行
|
\r\n
|
|||||
请求体,part1
|
——{boundary}
|
\r\n
|
||||
Content-Disposition
|
:
|
Form-data;name=“name"
|
\r\n
|
|||
\r\n
|
||||||
怪盗kidou
|
\r\n
|
|||||
请求体,part2
|
——{boundary}
|
\r\n
|
||||
Content-Disposition
|
:
|
Form-data;name=“file”;filename=“http.txt"
|
\r\n
|
|||
Content-Type
|
:
|
application/octet-stream
|
\r\n
|
|||
\r\n
|
||||||
This is text file
|
\r\n
|
|||||
请求体结束标志
|
——{boundary}——
|
\r\n
|
区分是否被当成文件的关键是Content-Disposition是否包含filename,因为文件有不同的类型,所以还要使用Content-Type指示文件的类型,如果不知道是什么类型的取值可以为application/octet-stream表示文件是一个二进制的文件,如果不是文件则Content-Type可以忽略。
HTTP的响应
HTTP响应的格式上除了状态行(第一行)与请求报文的请求行不一样之外,其他的就格式而言是一样的,但排除状态行和请求行的区别,从header上还是可以区分出HTTP请求和HTTP响应的区别的。
HTTP响应格式
|
||||||
响应状态行
|
协议版本
|
空格
|
响应码
|
空格
|
响应信息
|
\r\n
|
响应头
|
header1
|
:
|
value1
|
\r\n
|
||
header2
|
:
|
value2
|
\r\n
|
|||
header……
|
:
|
value……
|
\r\n
|
|||
headerN
|
:
|
valueN
|
\r\n
|
|||
空行
|
\r\n
|
|||||
响应体
|
响应体
|
|||||
-
状态码
状态码
|
对应的信息
|
1XX(临时响应码)
|
临时响应,表示请求已接收,继续处理
|
100 Continue
|
请求者应当继续提出请求。服务器已收到请求的一部分正在等待其余部分
|
101 Switching Protocols
|
切换协议,请求者已要求服务器切换协议,服务器已确认并准备切换,只能切换到更高级的协议
|
2XX(成功状态码)
|
用于表示请求已被成功接收
|
200 OK
|
从客户端发来的请求在服务器端被正常处理了。一般用于POST和GET请求
|
204 No Content
|
请求已经成功处理但是没有内容返回也不允许返回任何实体的主体。一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
|
206 Partial Content
|
表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容
|
3XX(重定向状态码)
|
用于表示资源(网页等)被永久转移到其他URL,也就是所谓的重定向
|
301 Moved Permanently
|
永久性重定向,表示请求的资源已经被分配了新的URI(统一资源标识符),以后应该使用资源现在所指的URI
|
302 Found
|
临时性重定向,表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。
|
303 See Other
|
表示由于请求对应的资源存在另一个URI,应该使用GET方法定向获取请求的资源
|
304 Not Modified
|
如果客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变。(协商缓存)
|
4XX(客户端错误状态码)
|
客户端错误——请求有语法错误/请求无法实现
|
400 Bad Request
|
报文中存在语法错误。浏览器会像对待200 OK一样对待该状态码
|
401 Unauthorized
|
发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。若之前已进行过一次请求,则表示用户认证失败。
|
403 Forbidden
|
请求资源的访问被服务器拒绝了。未获得文件系统的访问授权,访问权限出现问题等情况都会出现403。
|
404 Not Found
|
服务器无法找到请求的资源。服务器端拒绝请求且不想说明理由时也可以使用。
|
405 Method Not Allowed
|
客户端请求的方法虽然能被服务器识别,但是服务器禁止使用该方法,GET和HEAD应该总是允许客户端进行访问,客户端可以通过OPTIONS方法来查看服务器允许的访问方法。
|
5XX(服务器错误状态码)
|
服务器端错误——服务器未能实现合法的请求
|
500 Internal Server Error
|
服务器端在执行请求时发生了错误,也有可能是web应用存在的bug或者某些临时的故障
|
502 Bad Gateway
|
扮演网关或代理角色的服务器从上游服务器收到的响应是无效的。该错误需要有途径的web服务器或者代理服务器对其修复
|
503 Service Unavailable
|
服务器暂时处于超负荷或正在进行停机维护,现在无法处理请求。
|
-
响应头
响应头同样可用于传递一些附加信息
常见的响应Header:
名称
|
作用
|
Date
|
服务器的日期
|
Last-Modified
|
该资源最后被修改的时间
|
Transfer-Encoding
|
取值一般为chunked,出现在Content-Length不能确定的情况下,表示服务器不知道响应板体的数据大小,一般同时出现Content-Encoding响应头
|
Set-Cookie
|
设置cookie
|
Location
|
重定向到另一个URL,如输入浏览器就输入baidu.com回车,会自动跳转到www.baidu.com就是通过这个响应头控制的
|
Server
|
后台服务器
|
-
响应体
响应体也就是网页的正文内容,一般在响应头中会用 Content-Length 来明确响应体的长度,便于浏览器接收,对于大数据量的正文信息,也会使用 chunked 的编码方式。