一. 什么是HTTP协议
- HTTP协议是Hypertext Transfer Protocol(超文本传输协议)的缩写
- 主要用于World Wide Web(万维网)与浏览器之间传输超文本数据
- 可以传输各种格式的数据,例如图片,文本,附件等等
- 基于TCP/IP通信协议来传输数据
二. 工作方式
http_request_response.png
主要方式客户端-服务器模式
- 首先客户端发起一个http请求(request)报文
- 服务器回复一个响应(response)报文
三. URI和URL
- URI(Uniform Resource Identifier)统一资源标识符
- URL(Uniform Resource Locator)统一资源定位符
- URL是一种特殊的URI
- URL中包含了资源的请求方式和获取方法,而URI可以不包含
- URL的组成部分:protocol://hostname[:port]/path
- protocol:协议,例如http,ftp等等
- hostname:主机名,例如IP端口或者域名
- port:端口,可以为空
- path:路径,使用"/"分隔开
- 例如: http://www.baidu.com/
四. 请求方式
HTTP常用的请求方式有五种
- GET, 主要用于获取资源
- POST, 主要用于添加资源
- PUT, 主要用于更新资源
- DELETE, 主要用于删除资源
- OPTIONS, 和GET方式类似, 主要用于获取资源支持的HTTP请求方法
- GET和POST的区别:
- 协议层面只有语义上的不同
- 浏览器
- GET方式把参数拼接在URL后面,并且有长度限制
- POST方式把参数放在body中,理论上没有长度限制
五. 报文结构
HTTP报文主要有request和response两种
1.request报文结构
http request
- 请求行(request line): 包括请求方法,资源的URL,以及HTTP协议版本
- 请求头部(header): 包括请求服务器所需要的附加信息
- 空行(CRLF):请求头部后面必须是空行,即使请求数据为空,也要有空行
- 请求数据(body):也称为请求实体,可以添加任意类型的数据
2.response报文结构
http response
- 状态行(status line): 包括HTTP协议版本,状态码和状态消息组成
- 消息报头(header): 包括返回客户端的一些附件信息
- 空行(CRLF): 必须有空行
- 响应正文(body): 服务器返回给客户端的数据,可以是任意类型的数据
六.HTTP请求响应DEMO
1. GET方式
Request请求
GET /test?name=ygxing HTTP/1.1
Connection: keep-alive
Host: www.client.com
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)
Response请求
HTTP/1.1 200
Server: nginx/1.12.2
Date: Wed, 14 Mar 2018 01:33:03 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 44
Proxy-Connection: Keep-alive
{"status":1,"message":"success","data":null}
2.POST方式
Request请求
POST /test/ HTTP/1.1
Connection: keep-alive
Content-Type: application/json
Accept: application/json
Content-Length: 25
Host: www.client.com
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)
{"reports":["124","678"]}
Response请求
HTTP/1.1 200
Server: nginx/1.12.2
Date: Wed, 14 Mar 2018 00:52:07 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 44
Proxy-Connection: Keep-alive
{"status":1,"message":"success","data":null}
3.OPTIONS方式
Request请求
GET /test?name=ygxing HTTP/1.1
Connection: keep-alive
Host: www.client.com
User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_151)
Response请求
HTTP/1.1 200
Server: nginx/1.12.2
Date: Wed, 14 Mar 2018 00:55:21 GMT
Content-Length: 0
Allow: GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS
Proxy-Connection: Keep-alive
七.常用的HTTP消息头
消息头分为通用头(请求和响应共有的头部),请求头和响应头
1. 通用头
协议头 | 作用 | 示例 |
---|---|---|
Cache-Control | 指定请求和响应需要遵循的缓存机制 | Cache-Control:public,max-age=3600000 |
Connection | 是否需要持久化连接 | Connnection:keep-alive或者Connection:Upgrade |
Date | 消息发送的GMT时间 | Date: Tue, 04 Jun 2019 10:33:56 GMT |
Pragma | HTTP1.0协议中,该首部依赖于具体实现,向后兼容只支持缓存 | Pragma:no-cache |
Proxy-Authorization | 向代理服务器进行身份认证 | Proxy-Authorization:Bearer 123456 |
Transfer-Encoding | 内容编码方式,可以和Content-Encoding配合使用,也可以分块传输 | Transfer-Encoding:chunked |
Upgrade | 要求客户端或者服务器升级到另一个高版本协议 | Upgrade:websocket |
Via | 主要由代理服务器操作,表示请求或者响应经过了哪些代理服务器 | Via: 1.0 fred, 1.1 p.example.net |
Warning | 警告,其中会包含错误码,实体内容可能存在错误 | Warning: 112 - "cache down" "Wed, 21 Oct 2015 07:28:00 GMT" |
2. 请求头
协议头 | 作用 | 示例 |
---|---|---|
Accept | 客户端可以接受的响应内容类型 | Accept:text/html |
Accept-Charset | 客户端可接受的字符编码方式 | Accept-Charset:utf-8 |
Accept-Control-Request-Headers | 预检请求,告诉服务器真正请求使用的请求头 | Access-Control-Request-Headers: X-Custom-Header, Content-Type |
Accept-Control-Request-Method | 预检请求,告诉服务器真正请求使用的方法 | Access-Control-Request-Method: POST |
Accept-Encoding | 客户端可接受的内容编码方式,可以和Content-Encoding配合使用 | Accept-Encoding:deflate,gzip;q=1.0 |
Accept-Language | 客户端可接受的响应内容语言列表 | Accept-Language:zh-cn |
Authorization | 客户端携带的认证信息 | Bearer:xxxxxx |
Cookie | 客户端携带的Cookie数据,使用了session的话会携带一个SessionID | Cookie:jsessionid=xxxx |
Content-Security-Policy | 资源安全策略,可以控制资源的访问安全 | Content-Security-Policy: default-src https: |
Content-Type | 请求体的MIME类型 | Content-Type:application/json |
Expect | 客户端要求服务器做出的特定的行为 | Except:100-continue |
Host | 请求的服务器的IP和端口 | Host:127.0.0.1:8080 |
If-Match | 与ETag配合使用,当客户端提供的实体与服务器响应Etag相匹配时,才进行相应的操作,主要用于PUT请求 | If-Match:123456 |
If-Modified-Since | 配合ETag使用,如果资源在指定时间之前未经修改,返回一个没有body的304响应,如果资源在指定时间之前被修改,才会回复一个状态码为200并且携带资源的响应 | If-Modified-Since:Wed, 05 Jun 2019 03:03:25 GMT |
If-None-Match | 配合ETag使用,如果资源ETag不匹配,服务器才返回请求的资源,响应码为200,如果资源ETag匹配,服务器响应码为304 | If-None-Match:123456 |
If-Range | 规定了Range字段生效的条件,满足条件时,服务器响应码为206,返回部分资源,不满足条件时,服务器响应码为200,返回完整资源 | If-Range:Wed, 21 Oct 2015 07:28:00 GMT |
If-Unmodified-Since | 配合ETag使用,如果资源从指定时间起未被修改,那么服务器返回完整资源 | If-Unmodified-Since: Wed, 21 Oct 2015 07:28:00 GMT |
Max-Forwards | 限制请求消息可以被网关转发的次数 | Max-Forwards: 10 |
Origin | 请求的来源,只包含服务器的Host,不包含路径 | Origin: http://www.client.com |
Range | 配合If-Range使用,满足If-Range条件时,返回部分资源 | Range:bytes=500-900 |
Referer | 浏览器所访问的前一个页面 | Referer:http://www.client.com/index.html |
TE | 指定用户代理希望使用的传输编码类型 | TE: trailers, deflate;q=0.5 |
User-Agent | 浏览器的身份标识字符串 | User-Agent:Mozilla/... |
X-Requested-With | 判断客户端的请求是ajax还是其他请求 | X-Requested-With:"XMLHttpRequest" |
3. 响应头
协议头 | 作用 | 示例 |
---|---|---|
Access-Control-Allow-Credentials | 主要用户解决跨域问题,允许浏览器发送验证信息,例如Cookie,Authorization | Access-Control-Allow-Credentials:true |
Access-Control-Allow-Headers | 用于预检请求,返回的是正式请求有哪些头部 | Access-Control-Allow-Headers: X-Custom-Header |
Access-Control-Alllow-Methods | 用于预检请求,返回服务器支持的方法列表 | Access-Control-Allow-Methods: POST, GET, OPTIONS |
Access-Control-Allow-Origin | 允许哪些Origin跨域共享资源 | Access-Control-Allow-Origin:* |
Access-Control-Expose-Headers | 列出服务器支持的非简单响应头 | Access-Control-Expose-Headers: Content-Length, X-Custom-Header |
Accept-Patch | 指定服务器所支持的文档补丁格式 | Accept-Patch:text/properties;charset=utf-8 |
Accept-Range | 表示自身支持的请求范围 | Accept-Ranges: bytes |
Age | 响应对象在代理服务器缓存的时间(单位:秒) | Age: 600 |
Allow | 资源支持的请求方式 | Allow:GET,POST,HEAD |
Content-Disposition | 浏览器对于响应资源的动作,下载或者打开 | Content-Disposition: attachment; filename="filename.jpg" |
Content-Encoding | 响应数据的编码方式,客户端通过相应的方式解码,才能获取在Content-Type中标识的媒体类型 | Content-Encoding: gzip |
Content-Language | 响应内容所使用的语言 | Content-Language:zh-cn,en-US |
Content-Length | 响应数据的大小(单位字节) | Content-Length:200 |
Content-Location | 响应资源的候选位置 | Content-Location:/test/ |
Content-Range | 响应资源在整个文件中的位置 | Content-Range: bytes 200-1000/67589 |
Content-Type | 响应资源的类型 | Content-Type: text/html; charset=utf-8 |
ETag | 响应资源版本的标识,主要用于缓存 | ETag: "123456" |
Expires | 指定资源缓存超时日期 | Expires: Wed, 21 Oct 2015 07:28:00 GMT |
Strict-Transport-Security | 浏览器跳转到https | Strict-Transport-Security: max-age=31536000; includeSubDomains |
Last-Modified | 上次修改时间 | Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT |
Location | 浏览器自动重定向到Location对应的URL中 | Location:http://server.com/index.html |
P3P | 隐私策略,可以解决cookie跨域问题 | |
Public-Key-Pins | 服务端安全协议证书的公钥,降低伪造证书攻击的风险 | Public-Key-Pins:pin-sha256="cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=" |
Retry-After | 用户代理(浏览器)需要等待多久继续重试 | Retry-After: Wed, 21 Oct 2015 07:28:00 GMT |
Server | 服务器名称 | Server:nginx/12.0 |
Set-Cookie | 设置HTTP Cookie | Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/ |
Status | 服务器端状态码 | Status:200 OK |
Trailer | 分块消息添加的额外信息,例如数字签名,消息状态 | Trailer: Expires |
八.常用的HTTP错误码
- 状态码有三位数字组成
- 1xx表示请求已经收到,需要后续处理
- 2xx表示服务器成功处理了请求
- 3xx表示客户端需要进一步操作才能完成请求
- 4xx表示客户端请求错误
- 5xx表示服务器错误
1xx:请求已经收到,需要后续处理
状态码 | 消息 | 描述 |
---|---|---|
100 | Continue | 客户端应该继续发送请求, 服务器必须在请求完成后向客户端发送一个最终响应 |
101 | Switching Protocols | 服务器已经理解了客户端的请求, 并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求, 发送完这个响应之后, 服务器会切换到Upgrade消息头中定义的协议 |
102 | Processing | 服务器将继续进行处理 |
2xx:服务器成功处理了请求
状态码 | 消息 | 描述 |
---|---|---|
200 | OK | 请求已经成功 |
201 | Created | 请求已经被实现 |
202 | Accepted | 请求已经被接收,但还没有开始处理 |
203 | Non-Authoritative Information | 服务器已经成功处理了请求, 但是返回的实体头部元信息不是在原始服务器上有效的确定集合 |
204 | No Content | 服务器成功处理了请求, 但不需要返回任何实体内容 |
205 | Reset Content | 服务器成功处理了请求, 但不需要返回任何实体内容, 但与204不同之处在于该返回码要求请求者重置文档视图 |
206 | Partial Content | 服务器已经成功处理了部分GET请求 |
207 | Multi-Status | 表示之后的消息将是一个XML消息, 并且可能按照之前子请求数量的不同, 包含一系列独立的响应代码 |
3xx:客户端需要进一步操作才能完成请求
状态码 | 消息 | 描述 |
---|---|---|
300 | Multiple Choices | 被请求的资源有一系列可供选择的回馈信息, 客户端可以自行选择一个首选的地址进行重定向 |
301 | Moved Permanently | 被请求的资源已经被永久移动到新位置 |
302 | Move Temporarily | 请求的资源历史才能够不同的URI响应请求 |
303 | See Other | 对应的请求的响应可以在另一个URI上被找到 |
304 | Not Modified | 如果客户端发送了一个带条件的GET请求, 自上次访问以来文档的内容没有被修改, 那么服务器返回这个状态码 |
305 | Use Proxy | 被请求的资源必须通过制定的代理才能访问 |
306 | Switch Proxy | 在最新的规范中, 306状态码已经不再被使用 |
307 | Temporary Redirect | 请求的资源临时从不同的URI响应请求 |
4xx:客户端请求错误
状态码 | 消息 | 描述 |
---|---|---|
400 | Bad Request | 语义有误, 服务器无法理解, 除非进行修改, 否则客户端不应该重复提交该请求 |
401 | Unauthorized | 当前请求需要用户验证 |
402 | Payment Required | 预留状态码 |
403 | Forbidden | 服务器已经理解请求, 但是拒绝处理 |
404 | Not Found | 请求失败 请求的资源在服务器上找不到 |
405 | Method Not Allowed | 请求行中的请求方法不能被用于请求相应的资源 |
406 | Not Acceptable | 请求的资源内容无法满足请求头中的条件, 因而无法生成响应实体 |
407 | Proxy Authentication Required | 与401响应类似, 只是客户端必须在代理服务器上进行身份验证 |
408 | Request Timeout | 请求超时 |
409 | Conflict | 和被请求的资源的当前状态存在冲突, 请求无法完成 |
410 | Gone | 被请求的资源在服务器上已经不再可用, 而且没有任何已知的转发地址 |
411 | Length Required | 服务器拒绝在没有定义Content-Length头的情况下接受请求 |
412 | Precondition Failed | 服务器在验证请求的头字段给出了先决条件,请求没有满足其中的一个或者多个 |
413 | Request Entity Too Large | 请求的实体数据大小超过了服务器能够处理的范围 |
414 | Request-URI Too Long | 请求的URI长度超过了服务器能够解释的长度 |
415 | Unsupported Media Type | 请求提交的实体不是服务器支持的格式 |
416 | Requested Range Not Satisfiable | 请求中包含了Range请求头, 并且Range中指定的任何数据范围都与当前资源的可用范围不重合, 同时请求头中没有定义If-Range请求头 |
417 | Expectation Failed | 请求头中Expect中指定的预期内容没有被服务器满足 |
421 | Too Many Connections | 从当前客户端所在的IP地址到服务器的连接数已经超过了服务器许可的最大范围 |
422 | Unprocessable Entity | 请求格式正确, 但是语义错误 |
423 | Locked | 当前资源被锁定 |
424 | Failed Dependency | 由于之前的某个请求发生错误, 导致当前请求失败 |
425 | Unordered Collection | 还没有投入使用 |
426 | Upgrade Required | 客户端应该切换到TLS/1.0 |
449 | Retry With | 由微软扩展, 代表请求应该在完成适当的操作后重试 |
451 | 该请求因法律原因不可用 |
5xx:服务器错误
状态码 | 消息 | 描述 |
---|---|---|
500 | Internal Server Error | 服务器遇到了一个未曾预料的状况, 导致它无法完成对请求的处理 |
501 | Not Implemented | 服务器不支持请求所需要的某个功能 |
502 | Bad Gateway | 作为网关或者代理的服务器执行请求时, 从上游服务器收到无效的响应 |
503 | Service Unavailable | 服务器临时维护或者过载, 服务器当前无法处理请求 |
504 | Gateway Timeout | 网关或代理服务器尝试执行请求时, 未能及时从上游服务器(URI标识出来的服务器, 例如HTTP, FTP, LDAP)或者辅助服务器(例如DNS)收到响应 |
505 | HTTP Version Not Supported | 服务器不支持或者拒绝支持请求中使用的HTTP版本 |
506 | Variant Also Negotiates | 代表服务器存在内部配置错误 |
507 | Insufficient Storage | 服务器无法存储完成请求所需要的内容 |
509 | BandWidth Limit Exceeded | 服务器达到带宽限制 |
510 | Not Extended | 获取资源所需要的策略没有得到满足 |
600 | Unparseable Response Headers | 源站没有返回响应头部,只返回实体内容 |