深入理解HTTP协议

HTTP(Hyper Text Transfer Protocol) 超文本传输协议,是基于应用层(TCP/IP参考模型)的通信规范;是从Web服务器传输超文本到客户端的传输协议,无状态的传输协议;不仅能够保证正确、快速、高效的传输超文本文档,而且可以确定资源加载顺序等;在Web开发中,页面缓存控制、数据传递、文档语言参数设定等等,都离不开HTTP协议。HTTP协议是整个Web应用的基础,深入理解HTTP协议,是每个PHP开发工程师必须掌握的知识。

1. 引子:

我们访问一个网页,经历了三个步骤: 步骤1. 定位到网页所在服务器;步骤2. 按照一定格式传输到浏览器;步骤3.数据通过浏览器解析展示出来。

这三步流程分别应用到的主要技术:技术1. URL/DNS;技术2. HTTP协议;技术3. HTML/渲染。技术1和3暂时按下不表,步骤2中涉及的HTTP协议,如何构造而成?

我们看一下实例:
code 1:

➜  ~ curl -v https://www.baidu.com
* Rebuilt URL to: https://www.baidu.com/
*   Trying 119.75.216.20...
* TCP_NODELAY set
* Connected to www.baidu.com (119.75.216.20) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: baidu.com
* Server certificate: Symantec Class 3 Secure Server CA - G4
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> GET / HTTP/1.1
> Host: www.baidu.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Connection: Keep-Alive
< Content-Length: 2443
< Content-Type: text/html
< Date: Fri, 01 Sep 2017 02:22:25 GMT
< Etag: "588603eb-98b"
< Last-Modified: Mon, 23 Jan 2017 13:23:55 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc>这里是百度首页的正文</body> </html>
* Connection #0 to host www.baidu.com left intact
➜  ~

我们使用curl命令,输出请求百度首页的完整文档,根据每行前缀,可以分为四部分:
1. * 开头的行,状态行,本文不做详细介绍(其实小编也还没有弄清楚~~~,后续研究)
2. > 开头的行,是请求报文,常说的请求头
3. < 开头的行,是响应报文,常说的响应头
4. 没有前缀的行,line 28~29,是正文部分,要渲染到浏览器中的部分

在这个实例中,请求头、响应头格式内容,包括换行,还有文档具体内容,构成了HTTP协议。可以说,HTTP协议就是传输这些内容格式的规范。

现在我们对HTTP协议应该有了一个大致的概念了吧?具体的构成以及参数,我们下面细说。

2. HTTP 协议详解

HTTP 在TCP/IP参考模型中,位于应用层,通常承载于TCP协议之上。如果承载于TLS/SSL之上,就是HTTPS了。HTTP端口默认80,也会使用8080/8000端口;HTTPS端口443。HTTP 协议是以 ASCII 码传输。

2.1 HTTP 协议的特征:

  • HTTP 协议简单,请求一个网页时,只需发送请求方法(GET/POST/...)和资源路径(URI)。
  • HTTP 是无状态协议,本身对事务处理没有记忆能力,但是有专门的技术为HTTP请求提供会话能力:Cookie/Session
  • HTTP 采用问答式交互模型,每次连接只处理一个请求
  • HTTP 是标准的C/S模型
  • HTTP 允许传递数据对象类型丰富,由报头Content-Type标识

2.2 HTTP 协议由请求和响应两部分构成

  • 请求,又由3部分组成:请求行,消息报头,请求正文
  • 响应,也有3部分组成:状态行,消息报头,响应正文

2.3 HTTP请求工作流程

  • Client(通指Browser) 与 Web Server 建立连接
  • Client 发送请求,包括请求行、消息报头、请求正文,示例:GET / HTTP/1.1rnHost: www.baidu.comrn...
  • Server 发送响应,包括状态行、消息报头、响应正文,示例:HTTP/1.1 200 OKrnAccept-Ranges: bytesrn...
  • Client 展示用户数据,Client 与 Server 断开连接

2.4 HTTP 连接详解

在发送HTTP请求头之前,Client 要和 Server 建立连接;连接是传输层的实际环流,建立在两个相互通信的应用程序之间。

2.5 HTTP 请求详解

2.5.1.请求行
格式:Method URI HTTP-Version CRLF,示例:GET / HTTP/1.1rn
参数说明:

参数说明
Method请求方法,下面详解
URIURL的Path部分,资源标识符
HTTP-Version请求HTTP协议版本,目前常用是HTTP/1.1 版本,最新是 HTTP/2.0 版本
CRLFCRLF是Carriage-Return Line-Feed的缩写,意思是回车换行,就是回车(CR, ASCII 13, r) 换行(LF, ASCII 10, n)

2.5.2.请求方法
即我们常用到的GET、POST等等,如下表详解

方法说明
GET请求读取资源;GET操作是安全的。所谓安全是指不管进行多少次操作,资源的状态都不会改变。
POST一般用来想服务器提交数据,会创建新的数据,改变数据种类等资源;
POST 提交的数据必须放在消息主体(entity-body)
POST操作既不是安全的,也不是幂等的,如POST重复/提交问题。
与PUT相比,POST 是作用在一个集合资源之上的(/uri)
HEAD用来描述同样情况下的GET请求应该返回的响应消息报文,不应包含响应的实体,即不返回响应的正文。
在下载一个大文件前,使用HEAD方法获取文件大小等信息,再决定是否需要下载,节约带宽资源
使用CURL命令演示:
curl --head -X HEAD https://dldir1.qq.com/music/clntupate/mac/QQMusicMac_Mgr.dmg
PUTPUT请求是向服务器端发送数据的,用来修改数据,无论PUT多少次,结果相同。是等幂操作。
与POST相比,PUT操作是作用在一个具体资源之上的(/uri/xxx)
DELETE请求服务器删除资源,是等幂操作
TRACE请求服务器返回收到请求信息
该方法使得服务器原样返回任何客户端请求的内容,甚至包括路由中的代理服务器信息;
攻击者可以通过TRACE方法进行XSS/XST攻击,盗取会话Cookie、用户账户,模拟其他用户信息,篡改网页等;
Web服务器要关闭Trace方法,使用如下命令来查看服务器是否关闭了Trace方法:
curl --head -X TRACE https://dldir1.qq.com/music/clntupate/mac/QQMusicMac_Mgr.dmg
CONNECT保留备用
OPTIONSOPTIONS 是HTTP/1.1 协议中定义的方法
通过该方法,客户端在发起具体请求资源之前,获取服务器支持的HTTP请求方法,黑客常用;
检查服务器性能,在AJAX跨域请求中,需要向第三方资源发送 OPTIONS请求头,以判断实际发送的请求是否安全

注意:安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。

POST PUT 创建资源时区别

创建操作可以使用POST,也可以使用PUT,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确定,那么就使用POST
比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息只能由服务端提供,这个时候就必须使用POST。

 

2.5.3.请求正文
在Post/Put 请求中,需要传递数据到服务器,传递的数据就是请求正文部分,和报文部分以空行分隔。如下实例:

code 2:

➜  ~ curl -v --data-urlencode "name=kevhu.com" "http://127.0.0.1:8080" --trace-ascii /dev/stdout
Warning: --trace-ascii overrides an earlier trace/verbose option
== Info: Rebuilt URL to: http://127.0.0.1:8080/
== Info:   Trying 127.0.0.1...
== Info: TCP_NODELAY set
== Info: Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
=> Send header, 148 bytes (0x94)
0000: POST / HTTP/1.1
0011: Host: 127.0.0.1:8080
0027: User-Agent: curl/7.54.0
0040: Accept: */*
004d: Content-Length: 14
0061: Content-Type: application/x-www-form-urlencoded
0092:
=> Send data, 14 bytes (0xe)
0000: name=kevhu.com
== Info: upload completely sent off: 14 out of 14 bytes
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 22 bytes (0x16)
0000: Host: 127.0.0.1:8080
<= Recv header, 19 bytes (0x13)
0000: Connection: close
<= Recv header, 26 bytes (0x1a)
0000: X-Powered-By: PHP/7.0.17
<= Recv header, 40 bytes (0x28)
0000: Content-type: text/html; charset=UTF-8
<= Recv header, 2 bytes (0x2)
0000:
<= Recv data, 34 bytes (0x22)
0000: Array.(.    [name] => kevhu.com.).
Array
(
    [name] => kevhu.com
)
== Info: Closing connection 0

说明:
- ==行表示连接状态;=>发送请求报文的提示;<=接收响应报文的提示;其他行表示传递报文
- line 8~13: 请求行,和请求消息报文部分
- line 14: 空行,分隔报文和请求正文
- line 16: 请求正文部分,POST 请求提交给服务器的数据

2.6 HTTP 响应详解

2.6.1 状态行
格式:HTTP-Version Status-Code Reason-Phrase CRLF
示例:HTTP/1.1 200 OK rn
参数说明:

参数说明
HTTP-Version服务器HTTP协议的版本,目前常见是HTTP/1.1版本
Status-Code服务器发回的响应状态码,常见200、302、404、502 等
Reason-Phrase状态码的文本描述,如:OK、Not Allowed 等等
CRLFCRLF是Carriage-Return Line-Feed的缩写,意思是回车换行,就是回车(CR, ASCII 13, r) 换行(LF, ASCII 10, n)

2.6.2 状态码
常见有五种响应,由状态码的第一位数字标识出来:

状态码响应类型说明
1xx指示信息请求已接收,继续处理
2xx成功请求已被成功接收、接受、理解
3xx重定向要完成请求,必须进行进一步操作
4xx客户端错误请求有语法错误或请求无法实现
5xx服务端错误服务器未能实现合法的请求

常见HTTP Code 说明

CodePhrase说明
200OK客户端请求成功
400Bad Request客户端请求语法有误,服务器理解不了
401Unauthorize请求未经授权
403Forbidden服务器收到请求,但是拒绝提供服务,Nginx常见于文件权限配置错误时。
404Not Found请求资源不存在,比如错误的URL
500Internal Server Error服务器发生内部错误,一般是服务程序错误
502Gate Time Out网关cgi错误,比如请求数量超出PHP-FPM处理能力时,通过Nginx访问PHP程序,就会报该错误
503Server Unavailable服务器当前不能处理客户端的请求,一段时间后可能恢复正常

2.6.3 响应正文

参考code 2,来说明响应正文:

  • line 29:空行,分隔响应报头和响应正文
  • line 31:响应的正文部分

2.7 HTTP 核心消息报头详解

2.7.1 格式

  • 格式: Name: Value
  • 示例: Content-type: text/html; charset=UTF-8

2.7.2 HTTP消息报头通常分为四类:

  • 普通报头:有少数报头域,同时可以用于请求和响应消息,如缓存控制、连接控制
  • 请求报头:请求的附加信息以及客户端自身信息,如UA、Accept
  • 响应报头:服务器发回不能放到状态行的附加响应信息
  • 实体报头:定义了关于实体正文和请求所标记的资源的元信息,如:无实体正文

2.7.3 重要报头的说明

Name类型说明
Host请求指定请求资源的Internet主机地址和端口,必须表示请求资源的原始服务器/网关地址,通常域名形式表示。HTTP1.1版本,必须传递该报头
User-Agent请求客户端的身份信息,UA是辨别客户端设备的重要依据
Accept请求告诉服务器,客户端可以接受的文件格式。
Cookie请求发送Cookie信息到服务器端
Set-Cookie响应告诉客户端,需要设置一个Cookie;Cookie只能在客户端新增。
Cache-Control普通请求和响应遵循的缓存机制,互不影响
Referer请求访问来源地址,常用于记录访问者地址的参数
Content-Length响应服务器返回正文内容长度
Content-Range响应响应的资源范围,常用语断点续传
Accept-Encoding请求可以接受的编码方式

3. PHP HTTP 请求实例

实例演示HTTP 协议请求一个资源

首先准备一个Server文件,并启动一个PHP Web 服务:
code 3:

转载于:https://www.cnblogs.com/zhangzhijian/p/11176227.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值