一. 什么是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
四. 请求方式
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 |
源站没有返回响应头部,只返回实体内容 |
网友评论